]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - HLT/MUON/utils/dHLTdumpraw.cxx
Detecting endianess of platform at runtime and generating warning if not on a little...
[u/mrichter/AliRoot.git] / HLT / MUON / utils / dHLTdumpraw.cxx
index 7d1c6342255d9364be71f24e898782d27c1d307e..ad82fd84f5179aa5dd51c48fc5cc4c66f33f0f2c 100644 (file)
 // We define NDEBUG for the AliHLTMUONDataBlockReader.h header file since this
 // program by definition handles corrupt data. So we do not need the assertions
 // in the AliHLTMUONDataBlockReader class to be checked.
+#ifndef NDEBUG
 #define NDEBUG
+#endif
 #include "AliHLTMUONDataBlockReader.h"
+#if defined(DEBUG) && defined(NDEBUG)
 #undef NDEBUG
-#include "AliHLTMUONUtils.h"
-
-#include <endian.h>
-#ifndef LITTLE_ENDIAN
-#error Handling of internal data for non little endian machines not yet implemented.
 #endif
 
-#include <stdlib.h>
+#include "AliHLTMUONUtils.h"
+
+#include <cstdlib>
 #include <cassert>
 #include <new>
 #include <fstream>
@@ -132,7 +132,7 @@ int CheckField(
 
 template <typename BlockType>
 int CheckCommonHeader(
-               BlockType& block, const char* buffer, unsigned long bufferSize,
+               BlockType& block, const char* /*buffer*/, unsigned long bufferSize,
                bool continueParse
        )
 {
@@ -188,72 +188,237 @@ AliHLTUInt32_t CalculateNEntries(BlockType& block, unsigned long bufferSize)
 }
 
 
-int DumpTriggerRecordsBlock(
+int DumpRecHitStruct(
                const char* buffer, unsigned long bufferSize,
+               const AliHLTMUONRecHitStruct* hit,
                bool continueParse
        )
 {
-       AliHLTMUONTriggerRecordsBlockReader block(buffer, bufferSize);
-       // TODO
-       return EXIT_SUCCESS;
+       // Step through the fields trying to print them.
+       // At each step check if we have not overflowed the buffer. If we have
+       // not, then we can print the field, otherwise we print the left over
+       // bytes assumed to be corrupted rubbish.
+       int result = CheckField(hit->fX, buffer, bufferSize, continueParse);
+       if (result != EXIT_SUCCESS) return result;
+       cout << setw(13) << left << hit->fX << setw(0);
+
+       result = CheckField(hit->fY, buffer, bufferSize, continueParse);
+       if (result != EXIT_SUCCESS) return result;
+       cout << setw(13) << left << hit->fY << setw(0);
+
+       result = CheckField(hit->fZ, buffer, bufferSize, continueParse);
+       if (result != EXIT_SUCCESS) return result;
+       cout << hit->fZ << setw(0) << endl;
+
+       return result;
 }
 
 
-int DumpTrigRecsDebugBlock(
+int DumpRecHitsBlock(
                const char* buffer, unsigned long bufferSize,
                bool continueParse
        )
 {
-       AliHLTMUONTrigRecsDebugBlockReader block(buffer, bufferSize);
-       // TODO
-       return EXIT_SUCCESS;
+       int result = EXIT_SUCCESS;
+       AliHLTMUONRecHitsBlockReader block(buffer, bufferSize);
+       
+       result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
+       if (result != EXIT_SUCCESS and not continueParse) return result;
+       
+       AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
+       
+       // Print the data block record entries.
+       cout << " X (cm)     | Y (cm)     | Z (cm)" << endl;
+       cout << "---------------------------------------" << endl;
+       const AliHLTMUONRecHitStruct* entry = block.GetArray();
+       for(AliHLTUInt32_t i = 0; i < nentries; i++)
+       {
+               int subResult = DumpRecHitStruct(buffer, bufferSize, entry++, continueParse);
+               if (subResult != EXIT_SUCCESS) return subResult;
+       }
+       
+       return result;
 }
 
 
-int DumpTriggerChannelsBlock(
+int DumpTriggerRecordStruct(
+               const char* buffer, unsigned long bufferSize, 
+               const AliHLTMUONTriggerRecordStruct* record,
+               bool continueParse
+       )
+{
+       // Step through the fields trying to print them.
+       // At each step check if we have not overflowed the buffer. If we have
+       // not, then we can print the field, otherwise we print the left over
+       // bytes assumed to be corrupted rubbish.
+       int result = CheckField(record->fId, buffer, bufferSize, continueParse);
+       if (result != EXIT_SUCCESS) return result;
+       cout << "Trigger Record ID: " << record->fId <<endl;
+       
+       result = CheckField(record->fFlags, buffer, bufferSize, continueParse);
+       if (result != EXIT_SUCCESS) return result;
+       cout << "Flags: " << showbase << hex << record->fFlags << dec;
+               
+       // Print the individual trigger bits.
+       AliHLTMUONParticleSign sign;
+       bool hitset[4];
+       AliHLTMUONUtils::UnpackTriggerRecordFlags(record->fFlags, sign, hitset);
+       cout << " [Sign: " << sign << ", Hits set on chambers: ";
+       bool first = true;
+       for (AliHLTUInt32_t i = 0; i < 4; i++)
+       {
+               if (hitset[i])
+               {
+                       cout << (first ? "" : ", ") << i+11;
+                       first = false;
+               }
+       }
+       cout << (first ? "none]" : "]") << endl;
+
+       result = CheckField(record->fPx, buffer, bufferSize, continueParse);
+       if (result != EXIT_SUCCESS) return result;
+       cout << "Momentum: (px = " << record->fPx << ", ";
+
+       result = CheckField(record->fPy, buffer, bufferSize, continueParse);
+       if (result != EXIT_SUCCESS) return result;
+       cout << "py = " << record->fPy << ", ";
+
+       result = CheckField(record->fPz, buffer, bufferSize, continueParse);
+       if (result != EXIT_SUCCESS) return result;
+       cout << "pz = " << record->fPz << ") GeV/c"<<endl;
+       
+       cout << "Track hits:" << endl;
+       cout << "Chamber | X (cm)     | Y (cm)     | Z (cm)" << endl;
+       cout << "------------------------------------------------" << endl;
+       const AliHLTMUONRecHitStruct* hit = &record->fHit[0];
+       for(AliHLTUInt32_t ch = 0; ch < 4; ch++)
+       {
+               cout << setw(10) << left << ch + 11 << setw(0);
+               result = DumpRecHitStruct(buffer, bufferSize, hit++, continueParse);
+               if (result != EXIT_SUCCESS) return result;
+       }
+
+       return result;
+
+}
+
+
+int DumpTriggerRecordsBlock(
                const char* buffer, unsigned long bufferSize,
                bool continueParse
        )
 {
-       AliHLTMUONTriggerChannelsBlockReader block(buffer, bufferSize);
-       // TODO
+       AliHLTMUONTriggerRecordsBlockReader block(buffer, bufferSize);
+       
+       int result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
+       if (result != EXIT_SUCCESS and not continueParse) return result;
+       
+       AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
+       
+       // Print the data block record entries.
+       const AliHLTMUONTriggerRecordStruct* entry = block.GetArray();
+       for(AliHLTUInt32_t i = 0; i < nentries; i++)
+       {
+               cout << "============================== Trigger Record number " << i+1
+                       << " of " << nentries << " ==============================" << endl;
+               int subResult = DumpTriggerRecordStruct(buffer, bufferSize, entry++, continueParse);
+               if (subResult != EXIT_SUCCESS) return subResult;
+       }
+       
        return EXIT_SUCCESS;
 }
 
 
-int DumpRecHitStruct(
+int DumpTrigRecInfoStruct(const char* buffer, unsigned long bufferSize, 
+                          const AliHLTMUONTrigRecInfoStruct* debuginfo, 
+                          bool continueParse
+                          )
+{
+       // Step through the fields trying to print them.
+       // At each step check if we have not overflowed the buffer. If we have
+       // not, then we can print the field, otherwise we print the left over
+       // bytes assumed to be corrupted rubbish.
+       int result = CheckField(debuginfo->fTrigRecId, buffer, bufferSize, continueParse);
+       if (result != EXIT_SUCCESS) return result;
+       cout << setw(22) << left << debuginfo->fTrigRecId << setw(0);
+
+       result = CheckField(debuginfo->fDetElemId, buffer, bufferSize, continueParse);
+       if (result != EXIT_SUCCESS) return result;
+       cout << setw(20) << left << debuginfo->fDetElemId << setw(0);
+        
+       result = CheckField(debuginfo->fZmiddle, buffer, bufferSize, continueParse);
+       if(result != EXIT_SUCCESS) return result;
+       cout << setw(30) << left << debuginfo->fZmiddle << setw(0);
+
+       result = CheckField(debuginfo->fBl, buffer, bufferSize, continueParse);
+       if (result != EXIT_SUCCESS) return result;
+       cout <<debuginfo->fBl << setw(0) << endl;
+
+       return result;
+}
+
+
+int DumpTrigRecsDebugBlock(
                const char* buffer, unsigned long bufferSize,
-               const AliHLTMUONRecHitStruct* hit,
                bool continueParse
        )
+{
+       AliHLTMUONTrigRecsDebugBlockReader block(buffer, bufferSize);
+       
+       int result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
+       if (result != EXIT_SUCCESS and not continueParse) return result;
+       
+       AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
+       
+       // Print the data block record entries.
+       cout << "Trigger Record ID  | Detector ID  | Momentum X Component (Gev/c) | Integrated Magnetic Field (T.m)" << endl;
+       cout << "--------------------------------------------------------------------------------------------------" << endl;
+       const AliHLTMUONTrigRecInfoStruct* entry = block.GetArray();
+       for(AliHLTUInt32_t i = 0; i < nentries; i++)
+       {
+               int subResult = DumpTrigRecInfoStruct(buffer, bufferSize, entry++, continueParse);
+               if (subResult != EXIT_SUCCESS) return subResult;
+       }
+       
+       return EXIT_SUCCESS;
+}
+
+
+int DumpTriggerChannelStruct(const char* buffer, unsigned long bufferSize, 
+                      const AliHLTMUONTriggerChannelStruct* triggerchannel, 
+                      bool continueParse
+                      )
 {
        // Step through the fields trying to print them.
        // At each step check if we have not overflowed the buffer. If we have
        // not, then we can print the field, otherwise we print the left over
        // bytes assumed to be corrupted rubbish.
-       int result = CheckField(hit->fX, buffer, bufferSize, continueParse);
+       int result = CheckField(triggerchannel->fTrigRecId, buffer, bufferSize, continueParse);
        if (result != EXIT_SUCCESS) return result;
-       cout << setw(13) << left << hit->fX << setw(0);
+       cout << setw(25) << left << triggerchannel->fTrigRecId << setw(0);
 
-       result = CheckField(hit->fY, buffer, bufferSize, continueParse);
+       result = CheckField(triggerchannel->fChamber, buffer, bufferSize, continueParse);
        if (result != EXIT_SUCCESS) return result;
-       cout << setw(13) << left << hit->fY << setw(0);
+       cout << setw(13) << left << triggerchannel->fChamber << setw(0);
 
-       result = CheckField(hit->fZ, buffer, bufferSize, continueParse);
+       result = CheckField(triggerchannel->fSignal, buffer, bufferSize, continueParse);
        if (result != EXIT_SUCCESS) return result;
-       cout << hit->fZ << setw(0) << endl;
+       cout << setw(10) << left << triggerchannel->fSignal << setw(0);
 
+       result = CheckField(triggerchannel->fRawDataWord, buffer, bufferSize, continueParse);
+       if(result != EXIT_SUCCESS) return result;
+       cout << showbase << hex << triggerchannel->fRawDataWord << dec << setw(0) << endl;
        return result;
 }
 
 
-int DumpRecHitsBlock(
+int DumpTriggerChannelsBlock(
                const char* buffer, unsigned long bufferSize,
                bool continueParse
        )
 {
-       int result = EXIT_SUCCESS;
-       AliHLTMUONRecHitsBlockReader block(buffer, bufferSize);
+        int result = EXIT_SUCCESS;
+       AliHLTMUONTriggerChannelsBlockReader block(buffer, bufferSize);
        
        result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
        if (result != EXIT_SUCCESS and not continueParse) return result;
@@ -261,15 +426,47 @@ int DumpRecHitsBlock(
        AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
        
        // Print the data block record entries.
-       cout << " X (cm)     | Y (cm)     | Z (cm)" << endl;
-       cout << "---------------------------------------" << endl;
-       const AliHLTMUONRecHitStruct* entry = block.GetArray();
+       cout << " Trigger Record ID   | Chamber    | Signal   | Raw Data Word " << endl;
+       cout << "--------------------------------------------------------------" << endl;
+       const AliHLTMUONTriggerChannelStruct* entry = block.GetArray();
        for(AliHLTUInt32_t i = 0; i < nentries; i++)
        {
-               int subResult = DumpRecHitStruct(buffer, bufferSize, entry++, continueParse);
+               int subResult = DumpTriggerChannelStruct(buffer, bufferSize, entry++, continueParse);
                if (subResult != EXIT_SUCCESS) return subResult;
        }
-       
+
+       return result;
+}
+
+
+int DumpClusterStruct(
+                     const char* buffer, unsigned long bufferSize,
+                      const AliHLTMUONClusterStruct* cluster,
+                      bool continueParse
+       )
+{
+       // Step through the fields trying to print them.
+       // At each step check if we have not overflowed the buffer. If we have
+       // not, then we can print the field, otherwise we print the left over
+       // bytes assumed to be corrupted rubbish.
+       int result = CheckField(cluster->fId, buffer, bufferSize, continueParse);
+       if (result != EXIT_SUCCESS) return result;
+       cout << "cluster->fId: " << cluster->fId << "\t";
+
+       result = CheckField(cluster->fDetElemId, buffer, bufferSize, continueParse);
+       if (result != EXIT_SUCCESS) return result;
+       cout << "cluster->fDetElemId: " << cluster->fDetElemId << "\t";
+
+       result = CheckField(cluster->fNchannels, buffer, bufferSize, continueParse);
+       if(result != EXIT_SUCCESS) return result;
+       cout << "cluster->fNchannels: " << cluster->fNchannels <<endl;
+
+       cout << " Corresponding Hit: "<< endl;
+       cout << " X (cm)     | Y (cm)     | Z (cm)" << endl;
+       cout << "---------------------------------------" << endl;
+       const AliHLTMUONRecHitStruct * hit = & cluster->fHit;
+       result = DumpRecHitStruct(buffer, bufferSize, hit, continueParse);
+
        return result;
 }
 
@@ -279,9 +476,59 @@ int DumpClustersBlock(
                bool continueParse
        )
 {
+        int result = EXIT_SUCCESS;
        AliHLTMUONClustersBlockReader block(buffer, bufferSize);
-       // TODO
-       return EXIT_SUCCESS;
+       
+       result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
+       if (result != EXIT_SUCCESS and not continueParse) return result;
+       
+       AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
+       
+       // Print the data block record entries.
+       const AliHLTMUONClusterStruct* entry = block.GetArray();
+       for(AliHLTUInt32_t i = 0; i < nentries; i++)
+       {
+               cout << " ===================================================== Cluster Number "
+                       << i+1 << "==================================================" << endl; 
+               int subResult = DumpClusterStruct(buffer, bufferSize, entry++, continueParse);
+               if (subResult != EXIT_SUCCESS) return subResult;
+       }       
+
+       return result;
+}
+
+
+int DumpChannelStruct(
+               const char* buffer, unsigned long bufferSize,
+               const AliHLTMUONChannelStruct* channel,
+               bool continueParse                 
+       )
+{
+       // Step through the fields trying to print them.
+       // At each step check if we have not overflowed the buffer. If we have
+       // not, then we can print the field, otherwise we print the left over
+       // bytes assumed to be corrupted rubbish.
+       int result = CheckField(channel->fClusterId, buffer, bufferSize, continueParse);
+       if (result != EXIT_SUCCESS) return result;
+       cout << setw(16) << left << channel->fClusterId << setw(0);
+
+       result = CheckField(channel->fManu, buffer, bufferSize, continueParse);
+       if (result != EXIT_SUCCESS) return result;
+       cout << setw(16) << left << channel->fManu << setw(0);
+
+       result = CheckField(channel->fChannelAddress, buffer, bufferSize, continueParse);
+       if (result != EXIT_SUCCESS) return result;
+       cout << setw(19) << left << channel->fChannelAddress << setw(0);
+
+       result = CheckField(channel->fSignal, buffer, bufferSize, continueParse);
+       if(result != EXIT_SUCCESS) return result;
+       cout << setw(16) << left << channel->fSignal << setw(0);
+
+       result = CheckField(channel->fRawDataWord, buffer, bufferSize, continueParse);
+       if(result != EXIT_SUCCESS) return result;
+       cout << showbase << hex << channel->fRawDataWord << dec << setw(0) <<endl;
+
+       return result;
 }
 
 
@@ -290,8 +537,23 @@ int DumpChannelsBlock(
                bool continueParse
        )
 {
+        int result = EXIT_SUCCESS;
        AliHLTMUONChannelsBlockReader block(buffer, bufferSize);
-       // TODO
+       
+       result = CheckCommonHeader(block, buffer, bufferSize, continueParse);
+       if (result != EXIT_SUCCESS and not continueParse) return result;
+       
+       AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
+       
+       // Print the data block record entries.
+       cout << "Cluster Id  | Manu Address  | Channel Address  | Signal Value  | Raw Data Word " <<endl;
+       cout << "-------------------------------------------------------------------------------" <<endl;
+       const AliHLTMUONChannelStruct* entry = block.GetArray();
+       for(AliHLTUInt32_t i = 0; i < nentries; i++)
+       { 
+               int subResult = DumpChannelStruct(buffer, bufferSize, entry++, continueParse);
+               if (subResult != EXIT_SUCCESS) return subResult;
+       }
        return EXIT_SUCCESS;
 }
 
@@ -317,7 +579,7 @@ int DumpMansoTrackStruct(
        result = CheckField(track->fFlags, buffer, bufferSize, continueParse);
        if (result != EXIT_SUCCESS) return result;
        cout << "Flags: " << showbase << hex << track->fFlags << dec;
-               
+       
        // Print the individual trigger bits.
        AliHLTMUONParticleSign sign;
        bool hitset[4];
@@ -356,7 +618,7 @@ int DumpMansoTrackStruct(
        const AliHLTMUONRecHitStruct* hit = &track->fHit[0];
        for(AliHLTUInt32_t ch = 0; ch < 4; ch++)
        {
-               cout << setw(10) << ch + 7;
+               cout << setw(10) << left << ch + 7 << setw(0);
                result = DumpRecHitStruct(buffer, bufferSize, hit++, continueParse);
                if (result != EXIT_SUCCESS) return result;
        }
@@ -518,7 +780,10 @@ int DumpTrackDecisionStruct(
        AliHLTMUONUtils::UnpackTrackDecisionBits(decision->fTriggerBits, highPt, lowPt);
        cout << setw(7) << left << (highPt ? "yes" : "no");
        cout << setw(8) << left << (lowPt ? "yes" : "no");
-       cout << setw(0) << endl;
+       
+       result = CheckField(decision->fPt, buffer, bufferSize, continueParse);
+       if (result != EXIT_SUCCESS) return result;
+       cout << setw(0) << decision->fPt << endl;
 
        return result;
 }
@@ -543,9 +808,9 @@ int DumpSinglesDecisionBlock(
        AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize);
        
        // Print the data block record entries.
-       cout << "           |        Trigger Bits" << endl;
-       cout << "Track ID   | Raw         HighPt LowPt" << endl;
-       cout << "--------------------------------------" << endl;
+       cout << "           |        Trigger Bits      |" << endl;
+       cout << "Track ID   | Raw         HighPt LowPt | pT" << endl;
+       cout << "----------------------------------------------------" << endl;
        const AliHLTMUONTrackDecisionStruct* entry = block.GetArray();
        for(AliHLTUInt32_t i = 0; i < nentries; i++)
        {
@@ -890,29 +1155,33 @@ int ReadFile(const char* filename, char*& buffer, unsigned long& bufferSize)
 /**
  * Prints the command line usage of this program to standard error.
  */
-void PrintUsage()
+void PrintUsage(bool asError = true)
 {
-       cerr << "Usage: dHLTdumpraw [-help|-h] [-continue] [-type <typename>] <filename>" << endl;
-       cerr << "Where <filename> is the name of a file containing a raw data block." << endl;
-       cerr << "Options:" << endl;
-       cerr << " -help | -h" << endl;
-       cerr << "       Displays this message." << endl;
-       cerr << " -continue" << endl;
-       cerr << "       If specified, the program will try to continue parsing the data block" << endl;
-       cerr << "       as much as possible rather than stopping at the first error." << endl;
-       cerr << " -type <typename>" << endl;
-       cerr << "       Forces the contents of the file to be interpreted as a specific" << endl;
-       cerr << "       type of data block. Where <typename> can be one of:" << endl;
-       cerr << "         trigrecs - trigger records data." << endl;
-       cerr << "         trigrecsdebug - debugging information about trigger records." << endl;
-       cerr << "         trigchannels - channel debugging in." << endl;
-       cerr << "         rechits - reconstructed hits data." << endl;
-       cerr << "         channels - channel debugging information from hit reconstruction." << endl;
-       cerr << "         clusters - cluster debugging information from hit reconstruction." << endl;
-       cerr << "         mansotracks - partial tracks from Manso algorithm." << endl;
-       cerr << "         mansocandidates - track candidates considered in the Manso algorithm." << endl;
-       cerr << "         singlesdecision - trigger decisions for single tracks." << endl;
-       cerr << "         pairsdecision - trigger decisions for track pairs." << endl;
+       std::ostream& os = asError ? cerr : cout;
+       os << "Usage: dHLTdumpraw [-help|-h] [-continue] [-type <typename>] <filename>" << endl;
+       os << "Where <filename> is the name of a file containing a raw data block." << endl;
+       os << "Options:" << endl;
+       os << " -help | -h" << endl;
+       os << "       Displays this message." << endl;
+       os << " -continue" << endl;
+       os << "       If specified, the program will try to continue parsing the data block" << endl;
+       os << "       as much as possible rather than stopping at the first error." << endl;
+       os << " -type <typename>" << endl;
+       os << "       Forces the contents of the subsequent files specified on the command" << endl;
+       os << "       line to be interpreted as a specific type of data block." << endl;
+       os << "       Where <typename> can be one of:" << endl;
+       os << "         trigrecs - trigger records data." << endl;
+       os << "         trigrecsdebug - debugging information about trigger records." << endl;
+       os << "         trigchannels - channel debugging in." << endl;
+       os << "         rechits - reconstructed hits data." << endl;
+       os << "         channels - channel debugging information from hit reconstruction." << endl;
+       os << "         clusters - cluster debugging information from hit reconstruction." << endl;
+       os << "         mansotracks - partial tracks from Manso algorithm." << endl;
+       os << "         mansocandidates - track candidates considered in the Manso algorithm." << endl;
+       os << "         singlesdecision - trigger decisions for single tracks." << endl;
+       os << "         pairsdecision - trigger decisions for track pairs." << endl;
+       os << "         autodetect - the type of the data block will be automatically" << endl;
+       os << "                      detected." << endl;
 }
 
 /**
@@ -972,27 +1241,33 @@ AliHLTMUONDataBlockType ParseCommandLineType(const char* type)
  * Parses the command line.
  * @param argc  Number of arguments as given in main().
  * @param argv  Array of arguments as given in main().
- * @param filename  Receives the pointer to the file name string.
- * @param type      Receives the type of the data block expected, i.e. the
- *                  value of the -type flag.
+ * @param filenames  Pointer to buffer storing file name strings.
+ * @param numOfFiles  Receives the number of file name strings that were found
+ *                    and added to 'filenames'.
+ * @param filetypes  Array that receives the type of the data block expected, i.e.
+ *                   the value of the -type flag for the corresponding file.
  * @return  A status flag suitable for returning from main(), containing either
  *          EXIT_SUCCESS or CMDLINE_ERROR.
  */
 int ParseCommandLine(
-               int argc, const char** argv,
-               const char*& filename, bool& continueParse,
-               AliHLTMUONDataBlockType& type
+               int argc,
+               const char** argv,
+               const char** filenames,
+               int& numOfFiles,
+               bool& continueParse,
+               AliHLTMUONDataBlockType* filetypes
        )
 {
-       filename = NULL;
+       numOfFiles = 0;
        continueParse = false;
+       AliHLTMUONDataBlockType currentType = kUnknownDataBlock;
 
        // Parse the command line.
        for (int i = 1; i < argc; i++)
        {
                if (strcmp(argv[i], "-help") == 0 || strcmp(argv[i], "-h") == 0)
                {
-                       PrintUsage();
+                       PrintUsage(false);
                        return EXIT_SUCCESS;
                }
                else if (strcmp(argv[i], "-continue") == 0)
@@ -1001,29 +1276,36 @@ int ParseCommandLine(
                }
                else if (strcmp(argv[i], "-type") == 0)
                {
-                       // Now we need to parse the typename in the command line.
-                       type = ParseCommandLineType(argv[++i]);
-                       if (type == kUnknownDataBlock) return CMDLINE_ERROR;
-               }
-               else
-               {
-                       if (filename != NULL)
+                       if (++i >= argc)
                        {
-                               cerr << "ERROR: Only one file can be specified, but got '"
-                                       << argv[i] << "', with '" << filename
-                                       << "' specified earlier." << endl << endl;
+                               cerr << "ERROR: Missing a type specifier" << endl;
                                PrintUsage();
                                return CMDLINE_ERROR;
                        }
+                       // Now we need to parse the typename in the command line.
+                       if (strcmp(argv[i], "autodetect") == 0)
+                       {
+                               currentType = kUnknownDataBlock;
+                       }
                        else
-                               filename = argv[i];
+                       {
+                               currentType = ParseCommandLineType(argv[i]);
+                               if (currentType == kUnknownDataBlock) return CMDLINE_ERROR;
+                       }
+               }
+               else
+               {
+                       assert( numOfFiles < argc );
+                       filenames[numOfFiles] = argv[i];
+                       filetypes[numOfFiles] = currentType;
+                       numOfFiles++;
                }
        }
        
-       // Now check that we have the filename and all the flags we need.
-       if (filename == NULL)
+       // Now check that we have at least one filename and all the flags we need.
+       if (numOfFiles == 0)
        {
-               cerr << "ERROR: Missing a file name. You must specify a file to process."
+               cerr << "ERROR: Missing a file name. You must specify at least one file to process."
                        << endl << endl;
                PrintUsage();
                return CMDLINE_ERROR;
@@ -1035,25 +1317,71 @@ int ParseCommandLine(
 
 int main(int argc, const char** argv)
 {
-       const char* filename = NULL;
+       // Test endianess of this machine during runtime and print warning if it is not
+       // little endian.
+       union
+       {
+               int dword;
+               char byte[4];
+       } endianTest;
+       endianTest.dword = 0x1;
+       if (endianTest.byte[0] != 0x1)
+       {
+               cerr << "!!!! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !!!!!" << endl;
+               cerr << "!!!! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !!!!!" << endl;
+               cerr << "!!                                                                     !!" << endl;
+               cerr << "!! This is not a little endian machine, but dHLT raw data is normally  !!" << endl;
+               cerr << "!! generated in little endian format. Unless you are looking at localy !!" << endl;
+               cerr << "!! created simulated data, then this program will not show you correct !!" << endl;
+               cerr << "!! output.                                                             !!" << endl;
+               cerr << "!!                                                                     !!" << endl;
+               cerr << "!!!! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !!!!!" << endl;
+               cerr << "!!!! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !!!!!" << endl;
+               cerr << endl;
+       }
+
+
+       int numOfFiles = 0;
        bool continueParse = false;
        int returnCode = EXIT_SUCCESS;
-       AliHLTMUONDataBlockType type = kUnknownDataBlock;
        char* buffer = NULL;
 
        try
        {
-               returnCode = ParseCommandLine(argc, argv, filename, continueParse, type);
+               // There will be at least 'argc' number of filenames.
+               typedef const char* AnsiString;
+               const char** filename = new AnsiString[argc];
+               AliHLTMUONDataBlockType* filetype = new AliHLTMUONDataBlockType[argc];
+               
+               returnCode = ParseCommandLine(argc, argv, filename, numOfFiles, continueParse, filetype);
 
                if (returnCode == EXIT_SUCCESS)
                {
-                       unsigned long bufferSize = 0;
-                       returnCode = ReadFile(filename, buffer, bufferSize);
-                       if (returnCode == EXIT_SUCCESS)
-                               returnCode = ParseBuffer(buffer, bufferSize, continueParse, type);
-                       if (buffer != NULL) delete [] buffer;
+                       for (int i = 0; i < numOfFiles; i++)
+                       {
+                               unsigned long bufferSize = 0;
+                               returnCode = ReadFile(filename[i], buffer, bufferSize);
+                               if (returnCode != EXIT_SUCCESS) break;
+                               if (numOfFiles > 1)
+                               {
+                                       cout << "########## Start of dump for file: " << filename[i] << " ##########" << endl;
+                               }
+                               int result = ParseBuffer(buffer, bufferSize, continueParse, filetype[i]);
+                               if (buffer != NULL) delete [] buffer;
+                               if (result != EXIT_SUCCESS)
+                               {
+                                       returnCode = result;
+                                       if (not continueParse) break;
+                               }
+                               if (numOfFiles > 1)
+                               {
+                                       cout << "##########   End of dump for file: " << filename[i] << " ##########" << endl;
+                               }
+                       }
                }
                
+               delete [] filename;
+               delete [] filetype;
        }
        catch (...)
        {
@@ -1061,6 +1389,6 @@ int main(int argc, const char** argv)
                returnCode = FATAL_ERROR;
                if (buffer != NULL) delete [] buffer;
        }
-
+       
        return returnCode;
 }