3dad52b0 |
1 | /************************************************************************** |
2 | * Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. * |
3 | * * |
4 | * Author: * |
5 | * Contributors are mentioned in the code where appropriate. * |
6 | * * |
7 | * Permission to use, copy, modify and distribute this software and its * |
8 | * documentation strictly for non-commercial purposes is hereby granted * |
9 | * without fee, provided that the above copyright notice appears in all * |
10 | * copies and that both the copyright notice and this permission notice * |
11 | * appear in the supporting documentation. The authors make no claims * |
12 | * about the suitability of this software for any purpose. It is * |
13 | * provided "as is" without express or implied warranty. * |
14 | **************************************************************************/ |
15 | |
16 | /* $Id$ */ |
17 | |
18 | /** |
19 | * @file dHLTdumpraw.cxx |
20 | * @author Artur Szostak <artursz@iafrica.com>, |
21 | * Seforo Mohlalisi <seforomohlalisi@yahoo.co.uk> |
22 | * @date |
23 | * @brief Command line utility to dump dHLT's internal raw data blocks. |
24 | */ |
25 | |
26 | // We define NDEBUG for the AliHLTMUONDataBlockReader.h header file since this |
27 | // program by definition handles corrupt data. So we do not need the assertions |
28 | // in the AliHLTMUONDataBlockReader class to be checked. |
9c234d7b |
29 | #ifndef NDEBUG |
3dad52b0 |
30 | #define NDEBUG |
9c234d7b |
31 | #endif |
3dad52b0 |
32 | #include "AliHLTMUONDataBlockReader.h" |
9c234d7b |
33 | #if defined(DEBUG) && defined(NDEBUG) |
3dad52b0 |
34 | #undef NDEBUG |
9c234d7b |
35 | #endif |
36 | |
3dad52b0 |
37 | #include "AliHLTMUONUtils.h" |
38 | |
fdee2dad |
39 | /*TODO: fix this. Need a platform independant way of checking the endian encoding. |
40 | * This does not want to work on Apple Mac OS compiler: i686-apple-darw |
9c234d7b |
41 | * Handle this with #ifdef __APPLE__ ? |
3dad52b0 |
42 | #include <endian.h> |
43 | #ifndef LITTLE_ENDIAN |
44 | #error Handling of internal data for non little endian machines not yet implemented. |
45 | #endif |
fdee2dad |
46 | */ |
3dad52b0 |
47 | |
fdee2dad |
48 | #include <cstdlib> |
3dad52b0 |
49 | #include <cassert> |
50 | #include <new> |
51 | #include <fstream> |
52 | |
53 | #include <iostream> |
54 | using std::cout; |
55 | using std::cerr; |
56 | using std::endl; |
57 | using std::showbase; |
58 | using std::noshowbase; |
59 | using std::hex; |
60 | using std::dec; |
61 | |
62 | #include <iomanip> |
63 | using std::setw; |
64 | using std::left; |
65 | using std::internal; |
66 | |
67 | |
68 | #define CMDLINE_ERROR 1 |
69 | #define PARSE_ERROR 2 |
70 | #define SYSTEM_ERROR 3 |
71 | #define FATAL_ERROR 4 |
72 | |
73 | |
74 | void PrintRubbishData(AliHLTUInt32_t offset, const char* padByte, AliHLTUInt32_t padCount) |
75 | { |
76 | if (padCount == 0) return; |
77 | |
78 | cerr << "ERROR: Found the following unexpected rubbish data at the" |
79 | " end of the data block:" << endl; |
80 | cerr << "Byte #\tValue\tCharacter" << endl; |
81 | for (AliHLTUInt32_t i = 0; i < padCount; i++) |
82 | { |
83 | short value = short(padByte[i]) & 0xFF; |
84 | char character = padByte[i]; |
85 | cerr << offset + i + 1 << "\t" |
86 | << noshowbase << hex << "0x" << value << dec << "\t" |
87 | << character << endl; |
88 | } |
89 | } |
90 | |
91 | |
92 | template <typename FieldType> |
93 | int CheckHeaderField( |
94 | FieldType& field, const char* buffer, unsigned long bufferSize, |
95 | bool continueParse |
96 | ) |
97 | { |
98 | const char* fieldptr = reinterpret_cast<const char*>(&field); |
99 | const char* endptr = buffer + bufferSize; |
100 | AliHLTUInt32_t bufferRemaining = endptr > fieldptr ? endptr - fieldptr : 0; |
101 | |
102 | if (bufferRemaining < sizeof(field)) |
103 | { |
104 | cout << "..." << endl; // We may be half way through printing a line so end it. |
105 | cerr << "ERROR: The data block is too short. The header is corrupt." << endl; |
106 | if (continueParse) |
107 | { |
108 | AliHLTUInt32_t offset = fieldptr - buffer; |
109 | PrintRubbishData(offset, fieldptr, bufferRemaining); |
110 | } |
111 | return PARSE_ERROR; |
112 | } |
113 | return EXIT_SUCCESS; |
114 | } |
115 | |
116 | |
117 | template <typename FieldType> |
118 | int CheckField( |
119 | FieldType& field, const char* buffer, unsigned long bufferSize, |
120 | bool continueParse |
121 | ) |
122 | { |
123 | const char* fieldptr = reinterpret_cast<const char*>(&field); |
124 | const char* endptr = buffer + bufferSize; |
125 | AliHLTUInt32_t bufferRemaining = endptr > fieldptr ? endptr - fieldptr : 0; |
126 | |
127 | if (bufferRemaining < sizeof(field)) |
128 | { |
129 | cout << "..." << endl; // We may be half way through printing a line so end it. |
130 | cerr << "ERROR: The data block is too short. The data is corrupt." << endl; |
131 | if (continueParse) |
132 | { |
133 | AliHLTUInt32_t offset = fieldptr - buffer; |
134 | PrintRubbishData(offset, fieldptr, bufferRemaining); |
135 | } |
136 | return PARSE_ERROR; |
137 | } |
138 | return EXIT_SUCCESS; |
139 | } |
140 | |
141 | |
142 | template <typename BlockType> |
143 | int CheckCommonHeader( |
63ae97e0 |
144 | BlockType& block, const char* /*buffer*/, unsigned long bufferSize, |
3dad52b0 |
145 | bool continueParse |
146 | ) |
147 | { |
148 | int result = EXIT_SUCCESS; |
149 | |
150 | // Check the fRecordWidth field in the common header. |
151 | if (block.CommonBlockHeader().fRecordWidth != |
152 | sizeof(typename BlockType::ElementType)) |
153 | { |
154 | cerr << "ERROR: The record width found in the header is incorrect." |
155 | " Found a record width of " |
156 | << block.CommonBlockHeader().fRecordWidth << " bytes, but expected" |
157 | " a value of " << sizeof(typename BlockType::ElementType) |
158 | << " bytes." << endl; |
159 | result = PARSE_ERROR; |
160 | if (not continueParse) return result; |
161 | } |
162 | |
163 | if (not block.BufferSizeOk()) |
164 | { |
165 | cerr << "ERROR: The size of the file is incorrect. It is " |
166 | << bufferSize << " bytes big, but according" |
167 | " to the data block header it should be " << block.BytesUsed() |
168 | << " bytes." << endl; |
169 | result = PARSE_ERROR; |
170 | if (not continueParse) return result; |
171 | } |
172 | |
173 | return result; |
174 | } |
175 | |
176 | |
177 | template <typename BlockType> |
178 | AliHLTUInt32_t CalculateNEntries(BlockType& block, unsigned long bufferSize) |
179 | { |
180 | // Calculate how many entries we can display. If the buffer size is correct |
181 | // we just use the number of entries the block specifies. Otherwise we need |
182 | // to calculate it from the buffer size. |
183 | AliHLTUInt32_t nentries; |
184 | if (block.BytesUsed() == bufferSize) |
185 | { |
186 | nentries = block.Nentries(); |
187 | } |
188 | else |
189 | { |
190 | AliHLTInt32_t dataSize = bufferSize |
191 | - sizeof(typename BlockType::HeaderType); |
192 | nentries = dataSize / sizeof(typename BlockType::ElementType); |
193 | if (dataSize % sizeof(typename BlockType::ElementType) > 0) |
194 | nentries++; |
195 | } |
196 | return nentries; |
197 | } |
198 | |
199 | |
a68bc1e6 |
200 | int DumpRecHitStruct( |
3dad52b0 |
201 | const char* buffer, unsigned long bufferSize, |
a68bc1e6 |
202 | const AliHLTMUONRecHitStruct* hit, |
3dad52b0 |
203 | bool continueParse |
204 | ) |
205 | { |
a68bc1e6 |
206 | // Step through the fields trying to print them. |
207 | // At each step check if we have not overflowed the buffer. If we have |
208 | // not, then we can print the field, otherwise we print the left over |
209 | // bytes assumed to be corrupted rubbish. |
210 | int result = CheckField(hit->fX, buffer, bufferSize, continueParse); |
211 | if (result != EXIT_SUCCESS) return result; |
212 | cout << setw(13) << left << hit->fX << setw(0); |
213 | |
214 | result = CheckField(hit->fY, buffer, bufferSize, continueParse); |
215 | if (result != EXIT_SUCCESS) return result; |
216 | cout << setw(13) << left << hit->fY << setw(0); |
217 | |
218 | result = CheckField(hit->fZ, buffer, bufferSize, continueParse); |
219 | if (result != EXIT_SUCCESS) return result; |
220 | cout << hit->fZ << setw(0) << endl; |
221 | |
222 | return result; |
3dad52b0 |
223 | } |
224 | |
225 | |
a68bc1e6 |
226 | int DumpRecHitsBlock( |
3dad52b0 |
227 | const char* buffer, unsigned long bufferSize, |
228 | bool continueParse |
229 | ) |
230 | { |
a68bc1e6 |
231 | int result = EXIT_SUCCESS; |
232 | AliHLTMUONRecHitsBlockReader block(buffer, bufferSize); |
233 | |
234 | result = CheckCommonHeader(block, buffer, bufferSize, continueParse); |
235 | if (result != EXIT_SUCCESS and not continueParse) return result; |
236 | |
237 | AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize); |
238 | |
239 | // Print the data block record entries. |
240 | cout << " X (cm) | Y (cm) | Z (cm)" << endl; |
241 | cout << "---------------------------------------" << endl; |
242 | const AliHLTMUONRecHitStruct* entry = block.GetArray(); |
243 | for(AliHLTUInt32_t i = 0; i < nentries; i++) |
244 | { |
245 | int subResult = DumpRecHitStruct(buffer, bufferSize, entry++, continueParse); |
246 | if (subResult != EXIT_SUCCESS) return subResult; |
247 | } |
248 | |
249 | return result; |
3dad52b0 |
250 | } |
251 | |
252 | |
a68bc1e6 |
253 | int DumpTriggerRecordStruct( |
254 | const char* buffer, unsigned long bufferSize, |
255 | const AliHLTMUONTriggerRecordStruct* record, |
256 | bool continueParse |
257 | ) |
258 | { |
259 | // Step through the fields trying to print them. |
260 | // At each step check if we have not overflowed the buffer. If we have |
261 | // not, then we can print the field, otherwise we print the left over |
262 | // bytes assumed to be corrupted rubbish. |
263 | int result = CheckField(record->fId, buffer, bufferSize, continueParse); |
264 | if (result != EXIT_SUCCESS) return result; |
265 | cout << "Trigger Record ID: " << record->fId <<endl; |
266 | |
267 | result = CheckField(record->fFlags, buffer, bufferSize, continueParse); |
268 | if (result != EXIT_SUCCESS) return result; |
269 | cout << "Flags: " << showbase << hex << record->fFlags << dec; |
270 | |
271 | // Print the individual trigger bits. |
272 | AliHLTMUONParticleSign sign; |
273 | bool hitset[4]; |
274 | AliHLTMUONUtils::UnpackTriggerRecordFlags(record->fFlags, sign, hitset); |
275 | cout << " [Sign: " << sign << ", Hits set on chambers: "; |
276 | bool first = true; |
277 | for (AliHLTUInt32_t i = 0; i < 4; i++) |
278 | { |
279 | if (hitset[i]) |
280 | { |
281 | cout << (first ? "" : ", ") << i+11; |
282 | first = false; |
283 | } |
284 | } |
285 | cout << (first ? "none]" : "]") << endl; |
286 | |
287 | result = CheckField(record->fPx, buffer, bufferSize, continueParse); |
288 | if (result != EXIT_SUCCESS) return result; |
289 | cout << "Momentum: (px = " << record->fPx << ", "; |
290 | |
291 | result = CheckField(record->fPy, buffer, bufferSize, continueParse); |
292 | if (result != EXIT_SUCCESS) return result; |
293 | cout << "py = " << record->fPy << ", "; |
294 | |
295 | result = CheckField(record->fPz, buffer, bufferSize, continueParse); |
296 | if (result != EXIT_SUCCESS) return result; |
297 | cout << "pz = " << record->fPz << ") GeV/c"<<endl; |
298 | |
299 | cout << "Track hits:" << endl; |
300 | cout << "Chamber | X (cm) | Y (cm) | Z (cm)" << endl; |
301 | cout << "------------------------------------------------" << endl; |
302 | const AliHLTMUONRecHitStruct* hit = &record->fHit[0]; |
303 | for(AliHLTUInt32_t ch = 0; ch < 4; ch++) |
304 | { |
305 | cout << setw(10) << left << ch + 11 << setw(0); |
306 | result = DumpRecHitStruct(buffer, bufferSize, hit++, continueParse); |
307 | if (result != EXIT_SUCCESS) return result; |
308 | } |
309 | |
310 | return result; |
311 | |
312 | } |
313 | |
314 | |
315 | int DumpTriggerRecordsBlock( |
3dad52b0 |
316 | const char* buffer, unsigned long bufferSize, |
317 | bool continueParse |
318 | ) |
319 | { |
a68bc1e6 |
320 | AliHLTMUONTriggerRecordsBlockReader block(buffer, bufferSize); |
321 | |
322 | int result = CheckCommonHeader(block, buffer, bufferSize, continueParse); |
323 | if (result != EXIT_SUCCESS and not continueParse) return result; |
324 | |
325 | AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize); |
326 | |
327 | // Print the data block record entries. |
328 | const AliHLTMUONTriggerRecordStruct* entry = block.GetArray(); |
329 | for(AliHLTUInt32_t i = 0; i < nentries; i++) |
330 | { |
331 | cout << "============================== Trigger Record number " << i+1 |
332 | << " of " << nentries << " ==============================" << endl; |
333 | int subResult = DumpTriggerRecordStruct(buffer, bufferSize, entry++, continueParse); |
334 | if (subResult != EXIT_SUCCESS) return subResult; |
335 | } |
336 | |
3dad52b0 |
337 | return EXIT_SUCCESS; |
338 | } |
339 | |
340 | |
a68bc1e6 |
341 | int DumpTrigRecInfoStruct(const char* buffer, unsigned long bufferSize, |
342 | const AliHLTMUONTrigRecInfoStruct* debuginfo, |
343 | bool continueParse |
344 | ) |
345 | { |
346 | // Step through the fields trying to print them. |
347 | // At each step check if we have not overflowed the buffer. If we have |
348 | // not, then we can print the field, otherwise we print the left over |
349 | // bytes assumed to be corrupted rubbish. |
350 | int result = CheckField(debuginfo->fTrigRecId, buffer, bufferSize, continueParse); |
351 | if (result != EXIT_SUCCESS) return result; |
352 | cout << setw(22) << left << debuginfo->fTrigRecId << setw(0); |
353 | |
354 | result = CheckField(debuginfo->fDetElemId, buffer, bufferSize, continueParse); |
355 | if (result != EXIT_SUCCESS) return result; |
356 | cout << setw(20) << left << debuginfo->fDetElemId << setw(0); |
357 | |
358 | result = CheckField(debuginfo->fZmiddle, buffer, bufferSize, continueParse); |
359 | if(result != EXIT_SUCCESS) return result; |
360 | cout << setw(30) << left << debuginfo->fZmiddle << setw(0); |
361 | |
362 | result = CheckField(debuginfo->fBl, buffer, bufferSize, continueParse); |
363 | if (result != EXIT_SUCCESS) return result; |
364 | cout <<debuginfo->fBl << setw(0) << endl; |
365 | |
366 | return result; |
367 | } |
368 | |
369 | |
370 | int DumpTrigRecsDebugBlock( |
3dad52b0 |
371 | const char* buffer, unsigned long bufferSize, |
3dad52b0 |
372 | bool continueParse |
373 | ) |
a68bc1e6 |
374 | { |
375 | AliHLTMUONTrigRecsDebugBlockReader block(buffer, bufferSize); |
376 | |
377 | int result = CheckCommonHeader(block, buffer, bufferSize, continueParse); |
378 | if (result != EXIT_SUCCESS and not continueParse) return result; |
379 | |
380 | AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize); |
381 | |
382 | // Print the data block record entries. |
383 | cout << "Trigger Record ID | Detector ID | Momentum X Component (Gev/c) | Integrated Magnetic Field (T.m)" << endl; |
384 | cout << "--------------------------------------------------------------------------------------------------" << endl; |
385 | const AliHLTMUONTrigRecInfoStruct* entry = block.GetArray(); |
386 | for(AliHLTUInt32_t i = 0; i < nentries; i++) |
387 | { |
388 | int subResult = DumpTrigRecInfoStruct(buffer, bufferSize, entry++, continueParse); |
389 | if (subResult != EXIT_SUCCESS) return subResult; |
390 | } |
391 | |
392 | return EXIT_SUCCESS; |
393 | } |
394 | |
395 | |
396 | int DumpTriggerChannelStruct(const char* buffer, unsigned long bufferSize, |
397 | const AliHLTMUONTriggerChannelStruct* triggerchannel, |
398 | bool continueParse |
399 | ) |
3dad52b0 |
400 | { |
401 | // Step through the fields trying to print them. |
402 | // At each step check if we have not overflowed the buffer. If we have |
403 | // not, then we can print the field, otherwise we print the left over |
404 | // bytes assumed to be corrupted rubbish. |
a68bc1e6 |
405 | int result = CheckField(triggerchannel->fTrigRecId, buffer, bufferSize, continueParse); |
3dad52b0 |
406 | if (result != EXIT_SUCCESS) return result; |
a68bc1e6 |
407 | cout << setw(25) << left << triggerchannel->fTrigRecId << setw(0); |
3dad52b0 |
408 | |
a68bc1e6 |
409 | result = CheckField(triggerchannel->fChamber, buffer, bufferSize, continueParse); |
3dad52b0 |
410 | if (result != EXIT_SUCCESS) return result; |
a68bc1e6 |
411 | cout << setw(13) << left << triggerchannel->fChamber << setw(0); |
3dad52b0 |
412 | |
a68bc1e6 |
413 | result = CheckField(triggerchannel->fSignal, buffer, bufferSize, continueParse); |
3dad52b0 |
414 | if (result != EXIT_SUCCESS) return result; |
a68bc1e6 |
415 | cout << setw(10) << left << triggerchannel->fSignal << setw(0); |
3dad52b0 |
416 | |
a68bc1e6 |
417 | result = CheckField(triggerchannel->fRawDataWord, buffer, bufferSize, continueParse); |
418 | if(result != EXIT_SUCCESS) return result; |
419 | cout << showbase << hex << triggerchannel->fRawDataWord << dec << setw(0) << endl; |
3dad52b0 |
420 | return result; |
421 | } |
422 | |
423 | |
a68bc1e6 |
424 | int DumpTriggerChannelsBlock( |
3dad52b0 |
425 | const char* buffer, unsigned long bufferSize, |
426 | bool continueParse |
427 | ) |
428 | { |
a68bc1e6 |
429 | int result = EXIT_SUCCESS; |
430 | AliHLTMUONTriggerChannelsBlockReader block(buffer, bufferSize); |
3dad52b0 |
431 | |
432 | result = CheckCommonHeader(block, buffer, bufferSize, continueParse); |
433 | if (result != EXIT_SUCCESS and not continueParse) return result; |
434 | |
435 | AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize); |
436 | |
437 | // Print the data block record entries. |
a68bc1e6 |
438 | cout << " Trigger Record ID | Chamber | Signal | Raw Data Word " << endl; |
439 | cout << "--------------------------------------------------------------" << endl; |
440 | const AliHLTMUONTriggerChannelStruct* entry = block.GetArray(); |
3dad52b0 |
441 | for(AliHLTUInt32_t i = 0; i < nentries; i++) |
442 | { |
a68bc1e6 |
443 | int subResult = DumpTriggerChannelStruct(buffer, bufferSize, entry++, continueParse); |
3dad52b0 |
444 | if (subResult != EXIT_SUCCESS) return subResult; |
445 | } |
a68bc1e6 |
446 | |
447 | return result; |
448 | } |
449 | |
450 | |
451 | int DumpClusterStruct( |
452 | const char* buffer, unsigned long bufferSize, |
453 | const AliHLTMUONClusterStruct* cluster, |
454 | bool continueParse |
455 | ) |
456 | { |
457 | // Step through the fields trying to print them. |
458 | // At each step check if we have not overflowed the buffer. If we have |
459 | // not, then we can print the field, otherwise we print the left over |
460 | // bytes assumed to be corrupted rubbish. |
461 | int result = CheckField(cluster->fId, buffer, bufferSize, continueParse); |
462 | if (result != EXIT_SUCCESS) return result; |
463 | cout << "cluster->fId: " << cluster->fId << "\t"; |
464 | |
465 | result = CheckField(cluster->fDetElemId, buffer, bufferSize, continueParse); |
466 | if (result != EXIT_SUCCESS) return result; |
467 | cout << "cluster->fDetElemId: " << cluster->fDetElemId << "\t"; |
468 | |
469 | result = CheckField(cluster->fNchannels, buffer, bufferSize, continueParse); |
470 | if(result != EXIT_SUCCESS) return result; |
471 | cout << "cluster->fNchannels: " << cluster->fNchannels <<endl; |
472 | |
473 | cout << " Corresponding Hit: "<< endl; |
474 | cout << " X (cm) | Y (cm) | Z (cm)" << endl; |
475 | cout << "---------------------------------------" << endl; |
476 | const AliHLTMUONRecHitStruct * hit = & cluster->fHit; |
477 | result = DumpRecHitStruct(buffer, bufferSize, hit, continueParse); |
478 | |
3dad52b0 |
479 | return result; |
480 | } |
481 | |
482 | |
483 | int DumpClustersBlock( |
484 | const char* buffer, unsigned long bufferSize, |
485 | bool continueParse |
486 | ) |
487 | { |
a68bc1e6 |
488 | int result = EXIT_SUCCESS; |
3dad52b0 |
489 | AliHLTMUONClustersBlockReader block(buffer, bufferSize); |
a68bc1e6 |
490 | |
491 | result = CheckCommonHeader(block, buffer, bufferSize, continueParse); |
492 | if (result != EXIT_SUCCESS and not continueParse) return result; |
493 | |
494 | AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize); |
495 | |
496 | // Print the data block record entries. |
497 | const AliHLTMUONClusterStruct* entry = block.GetArray(); |
498 | for(AliHLTUInt32_t i = 0; i < nentries; i++) |
499 | { |
500 | cout << " ===================================================== Cluster Number " |
501 | << i+1 << "==================================================" << endl; |
502 | int subResult = DumpClusterStruct(buffer, bufferSize, entry++, continueParse); |
503 | if (subResult != EXIT_SUCCESS) return subResult; |
504 | } |
505 | |
506 | return result; |
507 | } |
508 | |
509 | |
510 | int DumpChannelStruct( |
511 | const char* buffer, unsigned long bufferSize, |
512 | const AliHLTMUONChannelStruct* channel, |
513 | bool continueParse |
514 | ) |
515 | { |
516 | // Step through the fields trying to print them. |
517 | // At each step check if we have not overflowed the buffer. If we have |
518 | // not, then we can print the field, otherwise we print the left over |
519 | // bytes assumed to be corrupted rubbish. |
520 | int result = CheckField(channel->fClusterId, buffer, bufferSize, continueParse); |
521 | if (result != EXIT_SUCCESS) return result; |
522 | cout << setw(16) << left << channel->fClusterId << setw(0); |
523 | |
524 | result = CheckField(channel->fManu, buffer, bufferSize, continueParse); |
525 | if (result != EXIT_SUCCESS) return result; |
526 | cout << setw(16) << left << channel->fManu << setw(0); |
527 | |
528 | result = CheckField(channel->fChannelAddress, buffer, bufferSize, continueParse); |
529 | if (result != EXIT_SUCCESS) return result; |
530 | cout << setw(19) << left << channel->fChannelAddress << setw(0); |
531 | |
532 | result = CheckField(channel->fSignal, buffer, bufferSize, continueParse); |
533 | if(result != EXIT_SUCCESS) return result; |
534 | cout << setw(16) << left << channel->fSignal << setw(0); |
535 | |
536 | result = CheckField(channel->fRawDataWord, buffer, bufferSize, continueParse); |
537 | if(result != EXIT_SUCCESS) return result; |
538 | cout << showbase << hex << channel->fRawDataWord << dec << setw(0) <<endl; |
539 | |
540 | return result; |
3dad52b0 |
541 | } |
542 | |
543 | |
544 | int DumpChannelsBlock( |
545 | const char* buffer, unsigned long bufferSize, |
546 | bool continueParse |
547 | ) |
548 | { |
a68bc1e6 |
549 | int result = EXIT_SUCCESS; |
3dad52b0 |
550 | AliHLTMUONChannelsBlockReader block(buffer, bufferSize); |
a68bc1e6 |
551 | |
552 | result = CheckCommonHeader(block, buffer, bufferSize, continueParse); |
553 | if (result != EXIT_SUCCESS and not continueParse) return result; |
554 | |
555 | AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize); |
556 | |
557 | // Print the data block record entries. |
558 | cout << "Cluster Id | Manu Address | Channel Address | Signal Value | Raw Data Word " <<endl; |
559 | cout << "-------------------------------------------------------------------------------" <<endl; |
560 | const AliHLTMUONChannelStruct* entry = block.GetArray(); |
561 | for(AliHLTUInt32_t i = 0; i < nentries; i++) |
562 | { |
563 | int subResult = DumpChannelStruct(buffer, bufferSize, entry++, continueParse); |
564 | if (subResult != EXIT_SUCCESS) return subResult; |
565 | } |
3dad52b0 |
566 | return EXIT_SUCCESS; |
567 | } |
568 | |
569 | |
570 | int DumpMansoTrackStruct( |
571 | const char* buffer, unsigned long bufferSize, |
572 | const AliHLTMUONMansoTrackStruct* track, |
573 | bool continueParse |
574 | ) |
575 | { |
576 | // Step through the fields trying to print them. |
577 | // At each step check if we have not overflowed the buffer. If we have |
578 | // not, then we can print the field, otherwise we print the left over |
579 | // bytes assumed to be corrupted rubbish. |
580 | int result = CheckField(track->fId, buffer, bufferSize, continueParse); |
581 | if (result != EXIT_SUCCESS) return result; |
582 | cout << "Track ID: " << track->fId << "\t"; |
583 | |
584 | result = CheckField(track->fTrigRec, buffer, bufferSize, continueParse); |
585 | if (result != EXIT_SUCCESS) return result; |
586 | cout << "Trigger Record ID: " << track->fTrigRec << endl; |
587 | |
588 | result = CheckField(track->fFlags, buffer, bufferSize, continueParse); |
589 | if (result != EXIT_SUCCESS) return result; |
590 | cout << "Flags: " << showbase << hex << track->fFlags << dec; |
a68bc1e6 |
591 | |
3dad52b0 |
592 | // Print the individual trigger bits. |
593 | AliHLTMUONParticleSign sign; |
594 | bool hitset[4]; |
595 | AliHLTMUONUtils::UnpackMansoTrackFlags(track->fFlags, sign, hitset); |
596 | cout << " [Sign: " << sign << ", Hits set on chambers: "; |
597 | bool first = true; |
598 | for (AliHLTUInt32_t i = 0; i < 4; i++) |
599 | { |
600 | if (hitset[i]) |
601 | { |
602 | cout << (first ? "" : ", ") << i+7; |
603 | first = false; |
604 | } |
605 | } |
606 | cout << (first ? "none]" : "]") << endl; |
607 | |
608 | result = CheckField(track->fPx, buffer, bufferSize, continueParse); |
609 | if (result != EXIT_SUCCESS) return result; |
610 | cout << "Momentum: (px = " << track->fPx << ", "; |
611 | |
612 | result = CheckField(track->fPy, buffer, bufferSize, continueParse); |
613 | if (result != EXIT_SUCCESS) return result; |
614 | cout << "py = " << track->fPy << ", "; |
615 | |
616 | result = CheckField(track->fPz, buffer, bufferSize, continueParse); |
617 | if (result != EXIT_SUCCESS) return result; |
618 | cout << "pz = " << track->fPz << ") GeV/c\t"; |
619 | |
620 | result = CheckField(track->fChi2, buffer, bufferSize, continueParse); |
621 | if (result != EXIT_SUCCESS) return result; |
622 | cout << "Chi squared fit: " << track->fChi2 << endl; |
623 | |
624 | cout << "Track hits:" << endl; |
625 | cout << "Chamber | X (cm) | Y (cm) | Z (cm)" << endl; |
626 | cout << "------------------------------------------------" << endl; |
627 | const AliHLTMUONRecHitStruct* hit = &track->fHit[0]; |
628 | for(AliHLTUInt32_t ch = 0; ch < 4; ch++) |
629 | { |
a68bc1e6 |
630 | cout << setw(10) << left << ch + 7 << setw(0); |
3dad52b0 |
631 | result = DumpRecHitStruct(buffer, bufferSize, hit++, continueParse); |
632 | if (result != EXIT_SUCCESS) return result; |
633 | } |
634 | |
635 | return result; |
636 | } |
637 | |
638 | |
639 | int DumpMansoTracksBlock( |
640 | const char* buffer, unsigned long bufferSize, |
641 | bool continueParse |
642 | ) |
643 | { |
644 | int result = EXIT_SUCCESS; |
645 | AliHLTMUONMansoTracksBlockReader block(buffer, bufferSize); |
646 | |
647 | result = CheckCommonHeader(block, buffer, bufferSize, continueParse); |
648 | if (result != EXIT_SUCCESS and not continueParse) return result; |
649 | |
650 | AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize); |
651 | |
652 | // Print the data block record entries. |
653 | const AliHLTMUONMansoTrackStruct* entry = block.GetArray(); |
654 | for(AliHLTUInt32_t i = 0; i < nentries; i++) |
655 | { |
656 | cout << "============================== Manso track number " << i+1 |
657 | << " of " << nentries << " ==============================" << endl; |
658 | int subResult = DumpMansoTrackStruct(buffer, bufferSize, entry++, continueParse); |
659 | if (subResult != EXIT_SUCCESS) return subResult; |
660 | } |
661 | |
662 | return result; |
663 | } |
664 | |
665 | |
666 | int DumpMansoRoIStruct( |
667 | const char* buffer, unsigned long bufferSize, |
668 | const AliHLTMUONMansoRoIStruct* roi, |
669 | bool continueParse |
670 | ) |
671 | { |
672 | // Step through the fields trying to print them. |
673 | // At each step check if we have not overflowed the buffer. If we have |
674 | // not, then we can print the field, otherwise we print the left over |
675 | // bytes assumed to be corrupted rubbish. |
676 | int result = CheckField(roi->fX, buffer, bufferSize, continueParse); |
677 | if (result != EXIT_SUCCESS) return result; |
678 | cout << setw(13) << left << roi->fX << setw(0); |
679 | |
680 | result = CheckField(roi->fY, buffer, bufferSize, continueParse); |
681 | if (result != EXIT_SUCCESS) return result; |
682 | cout << setw(13) << left << roi->fY << setw(0); |
683 | |
684 | result = CheckField(roi->fZ, buffer, bufferSize, continueParse); |
685 | if (result != EXIT_SUCCESS) return result; |
686 | cout << setw(13) << left << roi->fZ << setw(0); |
687 | |
688 | result = CheckField(roi->fRadius, buffer, bufferSize, continueParse); |
689 | if (result != EXIT_SUCCESS) return result; |
690 | cout << roi->fRadius << setw(0) << endl; |
691 | |
692 | return result; |
693 | } |
694 | |
695 | |
696 | int DumpMansoCandidateStruct( |
697 | const char* buffer, unsigned long bufferSize, |
698 | const AliHLTMUONMansoCandidateStruct* candidate, |
699 | bool continueParse |
700 | ) |
701 | { |
702 | int result = DumpMansoTrackStruct(buffer, bufferSize, &candidate->fTrack, continueParse); |
703 | if (result != EXIT_SUCCESS) return result; |
704 | |
705 | cout << "Regions of interest:" << endl; |
706 | cout << "Chamber | X (cm) | Y (cm) | Z (cm) | Radius (cm)" << endl; |
707 | cout << "-------------------------------------------------------------" << endl; |
708 | const AliHLTMUONMansoRoIStruct* roi = &candidate->fRoI[0]; |
709 | for(AliHLTUInt32_t ch = 0; ch < 4; ch++) |
710 | { |
711 | cout << setw(10) << ch + 7; |
712 | result = DumpMansoRoIStruct(buffer, bufferSize, roi++, continueParse); |
713 | if (result != EXIT_SUCCESS) return result; |
714 | } |
715 | return result; |
716 | } |
717 | |
718 | |
719 | int DumpMansoCandidatesBlock( |
720 | const char* buffer, unsigned long bufferSize, |
721 | bool continueParse |
722 | ) |
723 | { |
724 | int result = EXIT_SUCCESS; |
725 | AliHLTMUONMansoCandidatesBlockReader block(buffer, bufferSize); |
726 | |
727 | result = CheckCommonHeader(block, buffer, bufferSize, continueParse); |
728 | if (result != EXIT_SUCCESS and not continueParse) return result; |
729 | |
730 | AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize); |
731 | |
732 | // Print the data block record entries. |
733 | const AliHLTMUONMansoCandidateStruct* entry = block.GetArray(); |
734 | for(AliHLTUInt32_t i = 0; i < nentries; i++) |
735 | { |
736 | cout << "=========================== Manso track candidate number " << i+1 |
737 | << " of " << nentries << " ===========================" << endl; |
738 | int subResult = DumpMansoCandidateStruct(buffer, bufferSize, entry++, continueParse); |
739 | if (subResult != EXIT_SUCCESS) return subResult; |
740 | } |
741 | |
742 | return result; |
743 | } |
744 | |
745 | |
746 | int DumpSinglesDecisionBlockHeader( |
747 | const char* buffer, unsigned long bufferSize, |
748 | const AliHLTMUONSinglesDecisionBlockStruct* header, |
749 | bool continueParse |
750 | ) |
751 | { |
752 | // Step through the header fields trying to print them. |
753 | // At each step check if we have not overflowed the buffer, if we have |
754 | // not then we can print the field, otherwise we print the left over |
755 | // bytes assumed to be corrupted rubbish. |
756 | int result = CheckHeaderField(header->fNlowPt, buffer, bufferSize, continueParse); |
757 | if (result != EXIT_SUCCESS) return result; |
758 | cout << " Number of low pt triggers: " << header->fNlowPt << endl; |
759 | |
760 | result = CheckHeaderField(header->fNhighPt, buffer, bufferSize, continueParse); |
761 | if (result != EXIT_SUCCESS) return result; |
762 | cout << "Number of high pt triggers: " << header->fNhighPt << endl; |
763 | |
764 | return result; |
765 | } |
766 | |
767 | |
768 | int DumpTrackDecisionStruct( |
769 | const char* buffer, unsigned long bufferSize, |
770 | const AliHLTMUONTrackDecisionStruct* decision, |
771 | bool continueParse |
772 | ) |
773 | { |
774 | // Step through the fields trying to print them. |
775 | // At each step check if we have not overflowed the buffer. If we have |
776 | // not, then we can print the field, otherwise we print the left over |
777 | // bytes assumed to be corrupted rubbish. |
778 | int result = CheckField(decision->fTrackId, buffer, bufferSize, continueParse); |
779 | if (result != EXIT_SUCCESS) return result; |
780 | cout << setw(13) << left << decision->fTrackId << setw(0); |
781 | |
782 | result = CheckField(decision->fTriggerBits, buffer, bufferSize, continueParse); |
783 | if (result != EXIT_SUCCESS) return result; |
784 | cout << setw(12) << left << showbase << hex << decision->fTriggerBits |
785 | << setw(0) << dec; |
786 | |
787 | // Print the individual trigger bits. |
788 | bool highPt, lowPt; |
789 | AliHLTMUONUtils::UnpackTrackDecisionBits(decision->fTriggerBits, highPt, lowPt); |
790 | cout << setw(7) << left << (highPt ? "yes" : "no"); |
791 | cout << setw(8) << left << (lowPt ? "yes" : "no"); |
c9537879 |
792 | |
793 | result = CheckField(decision->fPt, buffer, bufferSize, continueParse); |
794 | if (result != EXIT_SUCCESS) return result; |
795 | cout << setw(0) << decision->fPt << endl; |
3dad52b0 |
796 | |
797 | return result; |
798 | } |
799 | |
800 | |
801 | int DumpSinglesDecisionBlock( |
802 | const char* buffer, unsigned long bufferSize, |
803 | bool continueParse |
804 | ) |
805 | { |
806 | int result = EXIT_SUCCESS; |
807 | AliHLTMUONSinglesDecisionBlockReader block(buffer, bufferSize); |
808 | |
809 | result = CheckCommonHeader(block, buffer, bufferSize, continueParse); |
810 | if (result != EXIT_SUCCESS and not continueParse) return result; |
811 | |
812 | // Dump the rest of the block header. |
813 | const AliHLTMUONSinglesDecisionBlockStruct* header = &block.BlockHeader(); |
814 | int subResult = DumpSinglesDecisionBlockHeader(buffer, bufferSize, header, continueParse); |
815 | if (subResult != EXIT_SUCCESS) return subResult; |
816 | |
817 | AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize); |
818 | |
819 | // Print the data block record entries. |
c9537879 |
820 | cout << " | Trigger Bits |" << endl; |
821 | cout << "Track ID | Raw HighPt LowPt | pT" << endl; |
822 | cout << "----------------------------------------------------" << endl; |
3dad52b0 |
823 | const AliHLTMUONTrackDecisionStruct* entry = block.GetArray(); |
824 | for(AliHLTUInt32_t i = 0; i < nentries; i++) |
825 | { |
826 | subResult = DumpTrackDecisionStruct(buffer, bufferSize, entry++, continueParse); |
827 | if (subResult != EXIT_SUCCESS) return subResult; |
828 | } |
829 | |
830 | return result; |
831 | } |
832 | |
833 | |
834 | int DumpPairsDecisionBlockHeader( |
835 | const char* buffer, unsigned long bufferSize, |
836 | const AliHLTMUONPairsDecisionBlockStruct* header, |
837 | bool continueParse |
838 | ) |
839 | { |
840 | // Step through the header fields trying to print them. |
841 | // At each step check if we have not overflowed the buffer, if we have |
842 | // not then we can print the field, otherwise we print the left over |
843 | // bytes assumed to be corrupted rubbish. |
844 | int result = CheckHeaderField(header->fNunlikeAnyPt, buffer, bufferSize, continueParse); |
845 | if (result != EXIT_SUCCESS) return result; |
846 | cout << " Number of unlike all pt triggers: " << header->fNunlikeAnyPt << endl; |
847 | |
848 | result = CheckHeaderField(header->fNunlikeLowPt, buffer, bufferSize, continueParse); |
849 | if (result != EXIT_SUCCESS) return result; |
850 | cout << " Number of unlike low pt triggers: " << header->fNunlikeLowPt << endl; |
851 | |
852 | result = CheckHeaderField(header->fNunlikeHighPt, buffer, bufferSize, continueParse); |
853 | if (result != EXIT_SUCCESS) return result; |
854 | cout << " Number of unlike high pt triggers: " << header->fNunlikeHighPt << endl; |
855 | |
856 | result = CheckHeaderField(header->fNlikeAnyPt, buffer, bufferSize, continueParse); |
857 | if (result != EXIT_SUCCESS) return result; |
858 | cout << " Number of like any pt triggers: " << header->fNlikeAnyPt << endl; |
859 | |
860 | result = CheckHeaderField(header->fNlikeLowPt, buffer, bufferSize, continueParse); |
861 | if (result != EXIT_SUCCESS) return result; |
862 | cout << " Number of like low pt triggers: " << header->fNlikeLowPt << endl; |
863 | |
864 | result = CheckHeaderField(header->fNlikeHighPt, buffer, bufferSize, continueParse); |
865 | if (result != EXIT_SUCCESS) return result; |
866 | cout << " Number of like high pt triggers: " << header->fNlikeHighPt << endl; |
867 | |
868 | result = CheckHeaderField(header->fNmassAny, buffer, bufferSize, continueParse); |
869 | if (result != EXIT_SUCCESS) return result; |
870 | cout << " Number of all invariant mass triggers: " << header->fNmassAny << endl; |
871 | |
872 | result = CheckHeaderField(header->fNmassLow, buffer, bufferSize, continueParse); |
873 | if (result != EXIT_SUCCESS) return result; |
874 | cout << " Number of low invariant mass triggers: " << header->fNmassLow << endl; |
875 | |
876 | result = CheckHeaderField(header->fNmassHigh, buffer, bufferSize, continueParse); |
877 | if (result != EXIT_SUCCESS) return result; |
878 | cout << "Number of high invariant mass triggers: " << header->fNmassHigh << endl; |
879 | |
880 | return result; |
881 | } |
882 | |
883 | |
884 | int DumpPairDecisionStruct( |
885 | const char* buffer, unsigned long bufferSize, |
886 | const AliHLTMUONPairDecisionStruct* decision, |
887 | bool continueParse |
888 | ) |
889 | { |
890 | // Step through the fields trying to print them. |
891 | // At each step check if we have not overflowed the buffer. If we have |
892 | // not, then we can print the field, otherwise we print the left over |
893 | // bytes assumed to be corrupted rubbish. |
894 | int result = CheckField(decision->fTrackAId, buffer, bufferSize, continueParse); |
895 | if (result != EXIT_SUCCESS) return result; |
896 | cout << setw(13) << left << decision->fTrackAId << setw(0); |
897 | |
898 | result = CheckField(decision->fTrackBId, buffer, bufferSize, continueParse); |
899 | if (result != EXIT_SUCCESS) return result; |
900 | cout << setw(13) << left << decision->fTrackBId << setw(0); |
901 | |
902 | result = CheckField(decision->fTriggerBits, buffer, bufferSize, continueParse); |
903 | if (result != EXIT_SUCCESS) return result; |
904 | cout << setw(12) << left << showbase << hex << decision->fTriggerBits |
905 | << setw(0) << dec; |
906 | |
907 | // Print the individual trigger bits. |
908 | bool highMass, lowMass, unlike; |
909 | AliHLTUInt8_t highPtCount, lowPtCount; |
910 | AliHLTMUONUtils::UnpackPairDecisionBits( |
911 | decision->fTriggerBits, |
912 | highMass, lowMass, unlike, highPtCount, lowPtCount |
913 | ); |
914 | cout << setw(7) << left << (highMass ? "yes" : "no"); |
915 | cout << setw(7) << left << (lowMass ? "yes" : "no"); |
916 | cout << setw(7) << left << (unlike ? "yes" : "no"); |
917 | cout << setw(6) << left << AliHLTUInt16_t(highPtCount); |
918 | cout << setw(8) << left << AliHLTUInt16_t(lowPtCount); |
919 | cout << setw(0); |
920 | |
921 | result = CheckField(decision->fInvMass, buffer, bufferSize, continueParse); |
922 | if (result != EXIT_SUCCESS) return result; |
923 | cout << decision->fInvMass << endl; |
924 | |
925 | return EXIT_SUCCESS; |
926 | } |
927 | |
928 | |
929 | int DumpPairsDecisionBlock( |
930 | const char* buffer, unsigned long bufferSize, |
931 | bool continueParse |
932 | ) |
933 | { |
934 | int result = EXIT_SUCCESS; |
935 | AliHLTMUONPairsDecisionBlockReader block(buffer, bufferSize); |
936 | |
937 | result = CheckCommonHeader(block, buffer, bufferSize, continueParse); |
938 | if (result != EXIT_SUCCESS and not continueParse) return result; |
939 | |
940 | // Dump the rest of the block header. |
941 | const AliHLTMUONPairsDecisionBlockStruct* header = &block.BlockHeader(); |
942 | int subResult = DumpPairsDecisionBlockHeader(buffer, bufferSize, header, continueParse); |
943 | if (subResult != EXIT_SUCCESS) return subResult; |
944 | |
945 | AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize); |
946 | |
947 | // Print the data block record entries. |
948 | cout << " | | Trigger Bits |" << endl; |
949 | cout << "Track A ID | Track B ID | Raw HiMass LoMass Unlike HiPt# LoPt# | Invariant mass" << endl; |
950 | cout << "----------------------------------------------------------------------------------------" << endl; |
951 | const AliHLTMUONPairDecisionStruct* entry = block.GetArray(); |
952 | for(AliHLTUInt32_t i = 0; i < nentries; i++) |
953 | { |
954 | subResult = DumpPairDecisionStruct(buffer, bufferSize, entry++, continueParse); |
955 | if (subResult != EXIT_SUCCESS) return subResult; |
956 | } |
957 | |
958 | return result; |
959 | } |
960 | |
961 | |
962 | int DumpCommonHeader( |
963 | const char* buffer, unsigned long bufferSize, |
964 | const AliHLTMUONDataBlockHeader* header, bool continueParse |
965 | ) |
966 | { |
967 | // Step through the header fields trying to print them. |
968 | // At each step check if we have not overflowed the buffer, if we have |
969 | // not then we can print the field, otherwise we print the left over |
970 | // bytes assumed to be corrupted rubbish. |
971 | int result = CheckHeaderField(header->fType, buffer, bufferSize, continueParse); |
972 | if (result != EXIT_SUCCESS) return result; |
973 | AliHLTMUONDataBlockType type = AliHLTMUONDataBlockType(header->fType); |
974 | cout << " Block type: " << type << endl; |
975 | |
976 | result = CheckHeaderField(header->fRecordWidth, buffer, bufferSize, continueParse); |
977 | if (result != EXIT_SUCCESS) return result; |
978 | cout << " Record width: " << header->fRecordWidth << endl; |
979 | |
980 | result = CheckHeaderField(header->fNrecords, buffer, bufferSize, continueParse); |
981 | if (result != EXIT_SUCCESS) return result; |
982 | cout << "Number of entries: " << header->fNrecords << endl; |
983 | |
984 | return result; |
985 | } |
986 | |
987 | |
988 | int ParseBuffer( |
989 | const char* buffer, unsigned long bufferSize, |
990 | bool continueParse, AliHLTMUONDataBlockType type |
991 | ) |
992 | { |
993 | assert( buffer != NULL ); |
994 | int result = EXIT_SUCCESS; |
995 | |
996 | if (bufferSize < sizeof(AliHLTMUONDataBlockHeader)) |
997 | { |
998 | cerr << "ERROR: The size of the file is too small to contain a" |
999 | " valid data block." << endl; |
1000 | result = PARSE_ERROR; |
1001 | if (not continueParse) return result; |
1002 | } |
1003 | const AliHLTMUONDataBlockHeader* header = |
1004 | reinterpret_cast<const AliHLTMUONDataBlockHeader*>(buffer); |
1005 | |
1006 | int subResult = DumpCommonHeader(buffer, bufferSize, header, continueParse); |
1007 | if (subResult != EXIT_SUCCESS) return subResult; |
1008 | |
1009 | |
1010 | // Check if the block type in the header corresponds to the type given |
1011 | // by the '-type' command line parameter. If they do not then print an |
1012 | // error or big fat warning message and force interpretation of the data |
1013 | // block with the type given by '-type'. |
1014 | AliHLTMUONDataBlockType headerType = AliHLTMUONDataBlockType(header->fType); |
1015 | |
1016 | if (type == kUnknownDataBlock) |
1017 | { |
1018 | // -type not used in the command line so just use what is given |
1019 | // by the data block header. |
1020 | type = headerType; |
1021 | } |
1022 | else if (type != headerType) |
1023 | { |
1024 | cerr << "WARNING: The data block header indicates a type" |
1025 | " different from what was specified on the command line." |
1026 | " The data could be corrupt." |
1027 | << endl; |
1028 | cerr << "WARNING: The type value in the file is " |
1029 | << showbase << hex << header->fType |
1030 | << " (" << headerType << "), but on the command line it is " |
1031 | << showbase << hex << int(type) << dec |
1032 | << " (" << type << ")." |
1033 | << endl; |
1034 | cerr << "WARNING: Will force the interpretation of the data block" |
1035 | " with a type of " << type << "." << endl; |
1036 | } |
1037 | |
1038 | // Now we know what type the data block is supposed to be so we can |
1039 | // dump it to screen with the appropriate dump routine. |
1040 | switch (type) |
1041 | { |
1042 | case kTriggerRecordsDataBlock: |
1043 | subResult = DumpTriggerRecordsBlock(buffer, bufferSize, continueParse); |
1044 | if (subResult != EXIT_SUCCESS) result = subResult; |
1045 | break; |
1046 | case kTrigRecsDebugDataBlock: |
1047 | subResult = DumpTrigRecsDebugBlock(buffer, bufferSize, continueParse); |
1048 | if (subResult != EXIT_SUCCESS) result = subResult; |
1049 | break; |
1050 | case kTriggerChannelsDataBlock: |
1051 | subResult = DumpTriggerChannelsBlock(buffer, bufferSize, continueParse); |
1052 | if (subResult != EXIT_SUCCESS) result = subResult; |
1053 | break; |
1054 | case kRecHitsDataBlock: |
1055 | subResult = DumpRecHitsBlock(buffer, bufferSize, continueParse); |
1056 | if (subResult != EXIT_SUCCESS) result = subResult; |
1057 | break; |
1058 | case kClustersDataBlock: |
1059 | subResult = DumpClustersBlock(buffer, bufferSize, continueParse); |
1060 | if (subResult != EXIT_SUCCESS) result = subResult; |
1061 | break; |
1062 | case kChannelsDataBlock: |
1063 | return DumpChannelsBlock(buffer, bufferSize, continueParse); |
1064 | if (subResult != EXIT_SUCCESS) result = subResult; |
1065 | break; |
1066 | case kMansoTracksDataBlock: |
1067 | subResult = DumpMansoTracksBlock(buffer, bufferSize, continueParse); |
1068 | if (subResult != EXIT_SUCCESS) result = subResult; |
1069 | break; |
1070 | case kMansoCandidatesDataBlock: |
1071 | subResult = DumpMansoCandidatesBlock(buffer, bufferSize, continueParse); |
1072 | if (subResult != EXIT_SUCCESS) result = subResult; |
1073 | break; |
1074 | case kSinglesDecisionDataBlock: |
1075 | subResult = DumpSinglesDecisionBlock(buffer, bufferSize, continueParse); |
1076 | if (subResult != EXIT_SUCCESS) result = subResult; |
1077 | break; |
1078 | case kPairsDecisionDataBlock: |
1079 | return DumpPairsDecisionBlock(buffer, bufferSize, continueParse); |
1080 | if (subResult != EXIT_SUCCESS) result = subResult; |
1081 | break; |
1082 | default : |
1083 | cout << "ERROR: Unknown data block type. Found a type number of " |
1084 | << showbase << hex << int(type) << dec |
1085 | << " (" << int(type) << ")." << endl; |
1086 | result = PARSE_ERROR; |
1087 | } |
1088 | |
1089 | return result; |
1090 | } |
1091 | |
1092 | |
1093 | /** |
1094 | * The caller is responsible for freeing memory allocated for buffer with a call |
1095 | * to delete [] buffer. |
1096 | */ |
1097 | int ReadFile(const char* filename, char*& buffer, unsigned long& bufferSize) |
1098 | { |
1099 | assert( filename != NULL ); |
1100 | |
1101 | // Open the file and find its size. |
1102 | fstream file; |
1103 | file.open(filename, ios::in); |
1104 | if (not file) |
1105 | { |
1106 | cerr << "ERROR: Could not open the file: " << filename << endl; |
1107 | return SYSTEM_ERROR; |
1108 | } |
1109 | file.seekg(0, ios::end); |
1110 | if (not file) |
1111 | { |
1112 | cerr << "ERROR: Could not seek in the file: " << filename << endl; |
1113 | return SYSTEM_ERROR; |
1114 | } |
1115 | bufferSize = file.tellg(); |
1116 | if (not file) |
1117 | { |
1118 | cerr << "ERROR: Could not get file size for the file: " << |
1119 | filename << endl; |
1120 | return SYSTEM_ERROR; |
1121 | } |
1122 | file.seekg(0, ios::beg); |
1123 | if (not file) |
1124 | { |
1125 | cerr << "ERROR: Could not seek in the file: " << filename << endl; |
1126 | return SYSTEM_ERROR; |
1127 | } |
1128 | |
1129 | // Allocate the memory for the file. |
1130 | try |
1131 | { |
1132 | buffer = new char[bufferSize]; |
1133 | } |
1134 | catch (const std::bad_alloc&) |
1135 | { |
1136 | cerr << "ERROR: Out of memory. Tried to allocate " << bufferSize |
1137 | << " bytes." << endl; |
1138 | return SYSTEM_ERROR; |
1139 | } |
1140 | |
1141 | file.read(buffer, bufferSize); |
1142 | if (not file) |
1143 | { |
1144 | delete [] buffer; |
1145 | buffer = NULL; |
1146 | bufferSize = 0; |
1147 | cerr << "ERROR: Could not read from file: " << filename << endl; |
1148 | return SYSTEM_ERROR; |
1149 | } |
1150 | |
1151 | file.close(); |
1152 | if (not file) |
1153 | { |
1154 | delete [] buffer; |
1155 | buffer = NULL; |
1156 | bufferSize = 0; |
1157 | cerr << "ERROR: Could not close the file: " << filename << endl; |
1158 | return SYSTEM_ERROR; |
1159 | } |
1160 | |
1161 | return EXIT_SUCCESS; |
1162 | } |
1163 | |
1164 | /** |
1165 | * Prints the command line usage of this program to standard error. |
1166 | */ |
c9537879 |
1167 | void PrintUsage(bool asError = true) |
3dad52b0 |
1168 | { |
c9537879 |
1169 | std::ostream& os = asError ? cerr : cout; |
1170 | os << "Usage: dHLTdumpraw [-help|-h] [-continue] [-type <typename>] <filename>" << endl; |
1171 | os << "Where <filename> is the name of a file containing a raw data block." << endl; |
1172 | os << "Options:" << endl; |
1173 | os << " -help | -h" << endl; |
1174 | os << " Displays this message." << endl; |
1175 | os << " -continue" << endl; |
1176 | os << " If specified, the program will try to continue parsing the data block" << endl; |
1177 | os << " as much as possible rather than stopping at the first error." << endl; |
1178 | os << " -type <typename>" << endl; |
1179 | os << " Forces the contents of the subsequent files specified on the command" << endl; |
1180 | os << " line to be interpreted as a specific type of data block." << endl; |
1181 | os << " Where <typename> can be one of:" << endl; |
1182 | os << " trigrecs - trigger records data." << endl; |
1183 | os << " trigrecsdebug - debugging information about trigger records." << endl; |
1184 | os << " trigchannels - channel debugging in." << endl; |
1185 | os << " rechits - reconstructed hits data." << endl; |
1186 | os << " channels - channel debugging information from hit reconstruction." << endl; |
1187 | os << " clusters - cluster debugging information from hit reconstruction." << endl; |
1188 | os << " mansotracks - partial tracks from Manso algorithm." << endl; |
1189 | os << " mansocandidates - track candidates considered in the Manso algorithm." << endl; |
1190 | os << " singlesdecision - trigger decisions for single tracks." << endl; |
1191 | os << " pairsdecision - trigger decisions for track pairs." << endl; |
1192 | os << " autodetect - the type of the data block will be automatically" << endl; |
1193 | os << " detected." << endl; |
3dad52b0 |
1194 | } |
1195 | |
1196 | /** |
1197 | * Parse the string passed as the type of the block and return the corresponding |
1198 | * AliHLTMUONDataBlockType value. |
1199 | */ |
1200 | AliHLTMUONDataBlockType ParseCommandLineType(const char* type) |
1201 | { |
1202 | if (strcmp(type, "trigrecs") == 0) |
1203 | { |
1204 | return kTriggerRecordsDataBlock; |
1205 | } |
1206 | else if (strcmp(type, "trigrecsdebug") == 0) |
1207 | { |
1208 | return kTrigRecsDebugDataBlock; |
1209 | } |
1210 | else if (strcmp(type, "trigchannels") == 0) |
1211 | { |
1212 | return kTriggerChannelsDataBlock; |
1213 | } |
1214 | else if (strcmp(type, "rechits") == 0) |
1215 | { |
1216 | return kRecHitsDataBlock; |
1217 | } |
1218 | else if (strcmp(type,"channels") == 0) |
1219 | { |
1220 | return kChannelsDataBlock; |
1221 | } |
1222 | else if (strcmp(type,"clusters") == 0) |
1223 | { |
1224 | return kClustersDataBlock; |
1225 | } |
1226 | else if (strcmp(type, "mansotracks") == 0) |
1227 | { |
1228 | return kMansoTracksDataBlock; |
1229 | } |
1230 | else if (strcmp(type, "mansocandidates") == 0) |
1231 | { |
1232 | return kMansoCandidatesDataBlock; |
1233 | } |
1234 | else if (strcmp(type, "singlesdecision") == 0) |
1235 | { |
1236 | return kSinglesDecisionDataBlock; |
1237 | } |
1238 | else if (strcmp(type, "pairsdecision") == 0) |
1239 | { |
1240 | return kPairsDecisionDataBlock; |
1241 | } |
1242 | |
1243 | cerr << "ERROR: Invalid type name '" << type << "' specified for argument -type." |
1244 | << endl << endl; |
1245 | PrintUsage(); |
1246 | return kUnknownDataBlock; |
1247 | } |
1248 | |
1249 | /** |
1250 | * Parses the command line. |
1251 | * @param argc Number of arguments as given in main(). |
1252 | * @param argv Array of arguments as given in main(). |
c9537879 |
1253 | * @param filenames Pointer to buffer storing file name strings. |
1254 | * @param numOfFiles Receives the number of file name strings that were found |
1255 | * and added to 'filenames'. |
1256 | * @param filetypes Array that receives the type of the data block expected, i.e. |
1257 | * the value of the -type flag for the corresponding file. |
3dad52b0 |
1258 | * @return A status flag suitable for returning from main(), containing either |
1259 | * EXIT_SUCCESS or CMDLINE_ERROR. |
1260 | */ |
1261 | int ParseCommandLine( |
c9537879 |
1262 | int argc, |
1263 | const char** argv, |
1264 | const char** filenames, |
1265 | int& numOfFiles, |
1266 | bool& continueParse, |
1267 | AliHLTMUONDataBlockType* filetypes |
3dad52b0 |
1268 | ) |
1269 | { |
c9537879 |
1270 | numOfFiles = 0; |
3dad52b0 |
1271 | continueParse = false; |
c9537879 |
1272 | AliHLTMUONDataBlockType currentType = kUnknownDataBlock; |
3dad52b0 |
1273 | |
1274 | // Parse the command line. |
1275 | for (int i = 1; i < argc; i++) |
1276 | { |
1277 | if (strcmp(argv[i], "-help") == 0 || strcmp(argv[i], "-h") == 0) |
1278 | { |
c9537879 |
1279 | PrintUsage(false); |
3dad52b0 |
1280 | return EXIT_SUCCESS; |
1281 | } |
1282 | else if (strcmp(argv[i], "-continue") == 0) |
1283 | { |
1284 | continueParse = true; |
1285 | } |
1286 | else if (strcmp(argv[i], "-type") == 0) |
1287 | { |
c9537879 |
1288 | if (++i >= argc) |
3dad52b0 |
1289 | { |
c9537879 |
1290 | cerr << "ERROR: Missing a type specifier" << endl; |
3dad52b0 |
1291 | PrintUsage(); |
1292 | return CMDLINE_ERROR; |
1293 | } |
c9537879 |
1294 | // Now we need to parse the typename in the command line. |
1295 | if (strcmp(argv[i], "autodetect") == 0) |
1296 | { |
1297 | currentType = kUnknownDataBlock; |
1298 | } |
3dad52b0 |
1299 | else |
c9537879 |
1300 | { |
1301 | currentType = ParseCommandLineType(argv[i]); |
1302 | if (currentType == kUnknownDataBlock) return CMDLINE_ERROR; |
1303 | } |
1304 | } |
1305 | else |
1306 | { |
1307 | assert( numOfFiles < argc ); |
1308 | filenames[numOfFiles] = argv[i]; |
1309 | filetypes[numOfFiles] = currentType; |
1310 | numOfFiles++; |
3dad52b0 |
1311 | } |
1312 | } |
1313 | |
c9537879 |
1314 | // Now check that we have at least one filename and all the flags we need. |
1315 | if (numOfFiles == 0) |
3dad52b0 |
1316 | { |
c9537879 |
1317 | cerr << "ERROR: Missing a file name. You must specify at least one file to process." |
3dad52b0 |
1318 | << endl << endl; |
1319 | PrintUsage(); |
1320 | return CMDLINE_ERROR; |
1321 | } |
1322 | |
1323 | return EXIT_SUCCESS; |
1324 | } |
1325 | |
1326 | |
1327 | int main(int argc, const char** argv) |
1328 | { |
c9537879 |
1329 | int numOfFiles = 0; |
3dad52b0 |
1330 | bool continueParse = false; |
1331 | int returnCode = EXIT_SUCCESS; |
3dad52b0 |
1332 | char* buffer = NULL; |
1333 | |
1334 | try |
1335 | { |
c9537879 |
1336 | // There will be at least 'argc' number of filenames. |
1337 | typedef const char* AnsiString; |
1338 | const char** filename = new AnsiString[argc]; |
1339 | AliHLTMUONDataBlockType* filetype = new AliHLTMUONDataBlockType[argc]; |
1340 | |
1341 | returnCode = ParseCommandLine(argc, argv, filename, numOfFiles, continueParse, filetype); |
3dad52b0 |
1342 | |
c9537879 |
1343 | if (returnCode == EXIT_SUCCESS) |
3dad52b0 |
1344 | { |
c9537879 |
1345 | for (int i = 0; i < numOfFiles; i++) |
1346 | { |
1347 | unsigned long bufferSize = 0; |
1348 | returnCode = ReadFile(filename[i], buffer, bufferSize); |
1349 | if (returnCode != EXIT_SUCCESS) break; |
a2be583d |
1350 | if (numOfFiles > 1) |
1351 | { |
1352 | cout << "########## Start of dump for file: " << filename[i] << " ##########" << endl; |
1353 | } |
c9537879 |
1354 | int result = ParseBuffer(buffer, bufferSize, continueParse, filetype[i]); |
1355 | if (buffer != NULL) delete [] buffer; |
1356 | if (result != EXIT_SUCCESS) |
1357 | { |
1358 | returnCode = result; |
1359 | if (not continueParse) break; |
1360 | } |
a2be583d |
1361 | if (numOfFiles > 1) |
1362 | { |
1363 | cout << "########## End of dump for file: " << filename[i] << " ##########" << endl; |
1364 | } |
c9537879 |
1365 | } |
3dad52b0 |
1366 | } |
1367 | |
c9537879 |
1368 | delete [] filename; |
1369 | delete [] filetype; |
3dad52b0 |
1370 | } |
1371 | catch (...) |
1372 | { |
1373 | cerr << "FATAL ERROR: An unknown exception occurred!" << endl << endl; |
1374 | returnCode = FATAL_ERROR; |
1375 | if (buffer != NULL) delete [] buffer; |
1376 | } |
c9537879 |
1377 | |
3dad52b0 |
1378 | return returnCode; |
1379 | } |