1 /**************************************************************************
2 * This file is property of and copyright by the ALICE HLT Project *
3 * All rights reserved. *
6 * Artur Szostak <artursz@iafrica.com> *
8 * Permission to use, copy, modify and distribute this software and its *
9 * documentation strictly for non-commercial purposes is hereby granted *
10 * without fee, provided that the above copyright notice appears in all *
11 * copies and that both the copyright notice and this permission notice *
12 * appear in the supporting documentation. The authors make no claims *
13 * about the suitability of this software for any purpose. It is *
14 * provided "as is" without express or implied warranty. *
15 **************************************************************************/
20 * @file dHLTrootify.cxx
21 * @author Artur Szostak <artursz@iafrica.com>
23 * @brief Command line utility to convert dHLT's internal raw data blocks into ROOT objects.
26 #include "TClassTable.h"
28 #include "AliHLTSystem.h"
29 #include "AliHLTConfiguration.h"
30 #include "AliHLTMUONDataBlockReader.h"
31 #include "AliHLTMUONConstants.h"
32 #include "AliHLTMUONUtils.h"
47 #define CMDLINE_ERROR 1
49 #define SYSTEM_ERROR 3
51 #define HLTSYSTEM_ERROR 5
55 * Uses AliHLTSystem and the AliHLTMUONRootifierComponent to convert the files
56 * into ROOT object format.
57 * @param filenames Array of file name strings.
58 * @param filetypes Array of file types corresponding to each filename.
59 * @param numOfFiles Number of entries in the 'filenames' and 'filetypes' arrays.
60 * @param outputFile The output file name to use.
61 * @param maxLogging If set then all debug messages are printed. (default = false)
62 * @param checkData Flag indicating if the internal raw data should be checked for
63 * consistency. Errors and warnings will be generated for consistency errors,
64 * but the rootification of the data will continue.
65 * @return Returns HLTSYSTEM_ERROR if there was a problem reported by AliHLTSystem
66 * and EXIT_SUCCESS if the ROOT file was created OK. SYSTEM_ERROR is
67 * returned if there was a problem allocating memory for HLT configuration
71 const char** filenames,
72 AliHLTMUONDataBlockType* filetypes,
74 const char* outputFile,
75 bool maxLogging = false,
76 bool checkData = false
83 AliLog::SetGlobalLogLevel(AliLog::kMaxType);
84 sys.SetGlobalLoggingLevel(kHLTLogAll);
87 // Check if required libraries are there and load them if not.
88 if (gClassTable->GetID("AliHLTAgentUtil") < 0)
90 sys.LoadComponentLibraries("libAliHLTUtil.so");
92 if (gClassTable->GetID("AliHLTMUONAgent") < 0)
94 sys.LoadComponentLibraries("libAliHLTMUON.so");
98 typedef AliHLTConfiguration* PAliHLTConfiguration;
99 PAliHLTConfiguration* filePubs = NULL;
103 filePubs = new PAliHLTConfiguration[numOfFiles];
104 // Must make sure all the pointers are NULL because we
105 // need to clean up afterwords and we might fail half
106 // way through the memory allocation.
108 for (i = 0; i < numOfFiles; i++)
113 // Now start allocating the file publishers.
114 for (i = 0; i < numOfFiles; i++)
116 TString name = "filePublisher_";
117 name += filenames[i];
118 sources += name + " ";
119 TString params = "-datatype '";
120 params += AliHLTMUONUtils::DataBlockTypeToString(filetypes[i]);
121 params += "' 'MUON' -dataspec 0x0 -datafile ";
122 params += filenames[i];
123 filePubs[i] = new AliHLTConfiguration(
124 name.Data(), "FilePublisher", NULL, params.Data()
128 catch (const std::bad_alloc&)
130 cerr << "ERROR: There is not enough memory to allocate another configuration object." << endl;
132 // Make sure to clean up what was actaully allocated.
133 if (filePubs != NULL)
135 for (int i = 0; i < numOfFiles; i++)
137 if (filePubs[i] != NULL)
146 // Setup the component for data integrity checking.
149 AliHLTConfiguration checker(
150 "checker", AliHLTMUONConstants::DataCheckerComponentId(),
151 sources, "-warn_on_unexpected_block -ignorespec"
156 // Setup the component which converts the raw internal dHLT data to ROOT objects.
157 AliHLTConfiguration convert("convert", AliHLTMUONConstants::RootifierComponentId(), sources, "");
159 // Setup the ROOT file writer.
160 TString params = "-concatenate-events -datafile ";
161 params += outputFile;
162 params += " -specfmt";
163 AliHLTConfiguration sink("sink", "ROOTFileWriter", "convert", params.Data());
165 // Build and run the HLT tasks.
166 if (sys.BuildTaskList("sink") != 0) return HLTSYSTEM_ERROR;
167 if (maxLogging) sys.PrintTaskList();
168 if (sys.Run() != 0) return HLTSYSTEM_ERROR;
170 // Clean up all the dynamically allocate objects.
171 for (int i = 0; i < numOfFiles; i++)
181 * This method decodes the type of the file.
183 int DecodeFileType(const char* filename, AliHLTMUONDataBlockType& type)
185 assert( filename != NULL );
187 // Open the file and find its size.
189 file.open(filename, ios::in);
192 cerr << "ERROR: Could not open the file: " << filename << endl;
196 AliHLTMUONDataBlockHeader header;
197 file.read(reinterpret_cast<char*>(&header), sizeof(header));
200 cerr << "ERROR: Could not read from file: " << filename << endl;
207 cerr << "ERROR: Could not close the file: " << filename << endl;
211 type = AliHLTMUONDataBlockType(header.fType);
213 // Check that the type is something valid. Otherwise set it to a
214 // value of kUnknownDataBlock.
217 case kTriggerRecordsDataBlock:
218 case kTrigRecsDebugDataBlock:
219 case kRecHitsDataBlock:
220 case kClustersDataBlock:
221 case kChannelsDataBlock:
222 case kMansoTracksDataBlock:
223 case kMansoCandidatesDataBlock:
224 case kSinglesDecisionDataBlock:
225 case kPairsDecisionDataBlock:
227 default: type = kUnknownDataBlock;
235 * Prints the command line usage of this program to standard out or error.
237 void PrintUsage(bool asError = true)
239 std::ostream& os = asError ? cerr : cout;
240 os << "Usage: dHLTrootify [-help|-h] [-outfile|-o <output_file>] [-type|-t <typename>]" << endl;
241 os << " [-debug|-d] [-check|-c] <filename> [<filename> ...]" << endl;
242 os << "Where <filename> is the name of a file containing a raw data block." << endl;
243 os << "Options:" << endl;
244 os << " -help | -h" << endl;
245 os << " Displays this message." << endl;
246 os << " -outfile | -o <output_file>" << endl;
247 os << " Specifies the output ROOT file to write to, where <output_file> is the" << endl;
248 os << " name of the output file." << endl;
249 os << " -type | -t <typename>" << endl;
250 os << " Forces the contents of the subsequent files specified on the command" << endl;
251 os << " line to be interpreted as a specific type of data block." << endl;
252 os << " Where <typename> can be one of:" << endl;
253 os << " trigrecs - trigger records data." << endl;
254 os << " trigrecsdebug - debugging information about trigger records." << endl;
255 os << " rechits - reconstructed hits data." << endl;
256 os << " channels - channel debugging information from hit reconstruction." << endl;
257 os << " clusters - cluster debugging information from hit reconstruction." << endl;
258 os << " mansotracks - partial tracks from Manso algorithm." << endl;
259 os << " mansocandidates - track candidates considered in the Manso algorithm." << endl;
260 os << " singlesdecision - trigger decisions for single tracks." << endl;
261 os << " pairsdecision - trigger decisions for track pairs." << endl;
262 os << " autodetect - the type of the data block will be automatically" << endl;
263 os << " detected." << endl;
264 os << " -debug | -d" << endl;
265 os << " If specified then the all debug messages are printed by the AliHLTSystem." << endl;
266 os << " -check | -c" << endl;
267 os << " If specified then data integrity checks are performed on the raw data." << endl;
268 os << " Warnings and errors are printed as problems are found with the data, but" << endl;
269 os << " the data will still be converted into ROOT objects as best as possible." << endl;
273 * Parses the command line.
274 * @param argc Number of arguments as given in main().
275 * @param argv Array of arguments as given in main().
276 * @param filenames Pointer to buffer storing file name strings.
277 * @param filetypes Array that receives the type of the data block expected, i.e.
278 * the value of the -type flag for the corresponding file.
279 * @param numOfFiles Receives the number of file name strings that were found
280 * and added to 'filenames'.
281 * @param outputFile The output file name to use. Set to NULL if none specified.
282 * @param maxLogging Set to true if maximal logging was requested.
283 * @param checkData Set to true if data integrity checking was requested.
284 * @return A status flag suitable for returning from main(), containing either
285 * EXIT_SUCCESS or CMDLINE_ERROR or SYSTEM_ERROR.
287 int ParseCommandLine(
290 const char** filenames,
291 AliHLTMUONDataBlockType* filetypes,
293 const char*& outputFile,
302 AliHLTMUONDataBlockType currentType = kUnknownDataBlock;
304 // Parse the command line.
305 for (int i = 1; i < argc; i++)
307 if (strcmp(argv[i], "-help") == 0 or strcmp(argv[i], "-h") == 0)
312 else if (strcmp(argv[i], "-outfile") == 0 or strcmp(argv[i], "-o") == 0)
316 cerr << "ERROR: Missing an output filename." << endl << endl;
318 return CMDLINE_ERROR;
320 outputFile = argv[i];
322 else if (strcmp(argv[i], "-type") == 0 or strcmp(argv[i], "-t") == 0)
326 cerr << "ERROR: Missing a type specifier." << endl << endl;
328 return CMDLINE_ERROR;
330 // Now we need to parse the typename in the command line.
331 if (strcmp(argv[i], "autodetect") == 0)
333 currentType = kUnknownDataBlock;
337 currentType = AliHLTMUONUtils::ParseCommandLineTypeString(argv[i]);
338 if (currentType == kUnknownDataBlock)
340 cerr << "ERROR: Invalid type name '" << argv[i]
341 << "' specified for argument " << argv[i-1]
342 << "." << endl << endl;
344 return CMDLINE_ERROR;
348 else if (strcmp(argv[i], "-debug") == 0 or strcmp(argv[i], "-d") == 0)
352 else if (strcmp(argv[i], "-check") == 0 or strcmp(argv[i], "-c") == 0)
358 assert( numOfFiles < argc );
359 filenames[numOfFiles] = argv[i];
361 AliHLTMUONDataBlockType typeToUse = currentType;
362 // Work out what the file type is from the file's header
363 // if the type is not yet known.
364 if (typeToUse == kUnknownDataBlock)
366 int result = DecodeFileType(filenames[numOfFiles], typeToUse);
367 if (result != EXIT_SUCCESS) return result;
368 if (typeToUse == kUnknownDataBlock)
370 cerr << "ERROR: Could not decode what type of data"
371 " is stored in the file:"
372 << filenames[numOfFiles] << endl;
377 filetypes[numOfFiles] = typeToUse;
382 // Now check that we have at least one filename and all the flags we need.
385 cerr << "ERROR: Missing a file name. You must specify at least one file to process."
388 return CMDLINE_ERROR;
395 int main(int argc, const char** argv)
397 // Test endianess of this machine during runtime and print warning if it is not
404 endianTest.dword = 0x1;
405 if (endianTest.byte[0] != 0x1)
407 cerr << "!!!! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !!!!!" << endl;
408 cerr << "!!!! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !!!!!" << endl;
409 cerr << "!! !!" << endl;
410 cerr << "!! This is not a little endian machine, but dHLT raw data is normally !!" << endl;
411 cerr << "!! generated in little endian format. Unless you are looking at localy !!" << endl;
412 cerr << "!! created simulated data, then this program will not show you correct !!" << endl;
413 cerr << "!! output. !!" << endl;
414 cerr << "!! !!" << endl;
415 cerr << "!!!! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !!!!!" << endl;
416 cerr << "!!!! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !!!!!" << endl;
422 const char* outputFile = NULL;
423 bool maxLogging = false;
424 bool checkData = false;
425 int returnCode = EXIT_SUCCESS;
429 // There will be a maximum of 'argc' number of filenames possible.
430 typedef const char* AnsiString;
431 const char** filename = new AnsiString[argc];
432 AliHLTMUONDataBlockType* filetype = new AliHLTMUONDataBlockType[argc];
434 returnCode = ParseCommandLine(
435 argc, argv, filename, filetype, numOfFiles,
436 outputFile, maxLogging, checkData
438 if (outputFile == NULL)
440 outputFile = "output.root";
442 if (returnCode == EXIT_SUCCESS)
444 returnCode = RootifyFiles(
445 filename, filetype, numOfFiles,
446 outputFile, maxLogging, checkData
455 cerr << "FATAL ERROR: An unknown exception occurred!" << endl << endl;
456 returnCode = FATAL_ERROR;