]>
Commit | Line | Data |
---|---|---|
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( | |
144 | BlockType& block, const char* buffer, unsigned long bufferSize, | |
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"); | |
792 | cout << setw(0) << endl; | |
793 | ||
794 | return result; | |
795 | } | |
796 | ||
797 | ||
798 | int DumpSinglesDecisionBlock( | |
799 | const char* buffer, unsigned long bufferSize, | |
800 | bool continueParse | |
801 | ) | |
802 | { | |
803 | int result = EXIT_SUCCESS; | |
804 | AliHLTMUONSinglesDecisionBlockReader block(buffer, bufferSize); | |
805 | ||
806 | result = CheckCommonHeader(block, buffer, bufferSize, continueParse); | |
807 | if (result != EXIT_SUCCESS and not continueParse) return result; | |
808 | ||
809 | // Dump the rest of the block header. | |
810 | const AliHLTMUONSinglesDecisionBlockStruct* header = &block.BlockHeader(); | |
811 | int subResult = DumpSinglesDecisionBlockHeader(buffer, bufferSize, header, continueParse); | |
812 | if (subResult != EXIT_SUCCESS) return subResult; | |
813 | ||
814 | AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize); | |
815 | ||
816 | // Print the data block record entries. | |
817 | cout << " | Trigger Bits" << endl; | |
818 | cout << "Track ID | Raw HighPt LowPt" << endl; | |
819 | cout << "--------------------------------------" << endl; | |
820 | const AliHLTMUONTrackDecisionStruct* entry = block.GetArray(); | |
821 | for(AliHLTUInt32_t i = 0; i < nentries; i++) | |
822 | { | |
823 | subResult = DumpTrackDecisionStruct(buffer, bufferSize, entry++, continueParse); | |
824 | if (subResult != EXIT_SUCCESS) return subResult; | |
825 | } | |
826 | ||
827 | return result; | |
828 | } | |
829 | ||
830 | ||
831 | int DumpPairsDecisionBlockHeader( | |
832 | const char* buffer, unsigned long bufferSize, | |
833 | const AliHLTMUONPairsDecisionBlockStruct* header, | |
834 | bool continueParse | |
835 | ) | |
836 | { | |
837 | // Step through the header fields trying to print them. | |
838 | // At each step check if we have not overflowed the buffer, if we have | |
839 | // not then we can print the field, otherwise we print the left over | |
840 | // bytes assumed to be corrupted rubbish. | |
841 | int result = CheckHeaderField(header->fNunlikeAnyPt, buffer, bufferSize, continueParse); | |
842 | if (result != EXIT_SUCCESS) return result; | |
843 | cout << " Number of unlike all pt triggers: " << header->fNunlikeAnyPt << endl; | |
844 | ||
845 | result = CheckHeaderField(header->fNunlikeLowPt, buffer, bufferSize, continueParse); | |
846 | if (result != EXIT_SUCCESS) return result; | |
847 | cout << " Number of unlike low pt triggers: " << header->fNunlikeLowPt << endl; | |
848 | ||
849 | result = CheckHeaderField(header->fNunlikeHighPt, buffer, bufferSize, continueParse); | |
850 | if (result != EXIT_SUCCESS) return result; | |
851 | cout << " Number of unlike high pt triggers: " << header->fNunlikeHighPt << endl; | |
852 | ||
853 | result = CheckHeaderField(header->fNlikeAnyPt, buffer, bufferSize, continueParse); | |
854 | if (result != EXIT_SUCCESS) return result; | |
855 | cout << " Number of like any pt triggers: " << header->fNlikeAnyPt << endl; | |
856 | ||
857 | result = CheckHeaderField(header->fNlikeLowPt, buffer, bufferSize, continueParse); | |
858 | if (result != EXIT_SUCCESS) return result; | |
859 | cout << " Number of like low pt triggers: " << header->fNlikeLowPt << endl; | |
860 | ||
861 | result = CheckHeaderField(header->fNlikeHighPt, buffer, bufferSize, continueParse); | |
862 | if (result != EXIT_SUCCESS) return result; | |
863 | cout << " Number of like high pt triggers: " << header->fNlikeHighPt << endl; | |
864 | ||
865 | result = CheckHeaderField(header->fNmassAny, buffer, bufferSize, continueParse); | |
866 | if (result != EXIT_SUCCESS) return result; | |
867 | cout << " Number of all invariant mass triggers: " << header->fNmassAny << endl; | |
868 | ||
869 | result = CheckHeaderField(header->fNmassLow, buffer, bufferSize, continueParse); | |
870 | if (result != EXIT_SUCCESS) return result; | |
871 | cout << " Number of low invariant mass triggers: " << header->fNmassLow << endl; | |
872 | ||
873 | result = CheckHeaderField(header->fNmassHigh, buffer, bufferSize, continueParse); | |
874 | if (result != EXIT_SUCCESS) return result; | |
875 | cout << "Number of high invariant mass triggers: " << header->fNmassHigh << endl; | |
876 | ||
877 | return result; | |
878 | } | |
879 | ||
880 | ||
881 | int DumpPairDecisionStruct( | |
882 | const char* buffer, unsigned long bufferSize, | |
883 | const AliHLTMUONPairDecisionStruct* decision, | |
884 | bool continueParse | |
885 | ) | |
886 | { | |
887 | // Step through the fields trying to print them. | |
888 | // At each step check if we have not overflowed the buffer. If we have | |
889 | // not, then we can print the field, otherwise we print the left over | |
890 | // bytes assumed to be corrupted rubbish. | |
891 | int result = CheckField(decision->fTrackAId, buffer, bufferSize, continueParse); | |
892 | if (result != EXIT_SUCCESS) return result; | |
893 | cout << setw(13) << left << decision->fTrackAId << setw(0); | |
894 | ||
895 | result = CheckField(decision->fTrackBId, buffer, bufferSize, continueParse); | |
896 | if (result != EXIT_SUCCESS) return result; | |
897 | cout << setw(13) << left << decision->fTrackBId << setw(0); | |
898 | ||
899 | result = CheckField(decision->fTriggerBits, buffer, bufferSize, continueParse); | |
900 | if (result != EXIT_SUCCESS) return result; | |
901 | cout << setw(12) << left << showbase << hex << decision->fTriggerBits | |
902 | << setw(0) << dec; | |
903 | ||
904 | // Print the individual trigger bits. | |
905 | bool highMass, lowMass, unlike; | |
906 | AliHLTUInt8_t highPtCount, lowPtCount; | |
907 | AliHLTMUONUtils::UnpackPairDecisionBits( | |
908 | decision->fTriggerBits, | |
909 | highMass, lowMass, unlike, highPtCount, lowPtCount | |
910 | ); | |
911 | cout << setw(7) << left << (highMass ? "yes" : "no"); | |
912 | cout << setw(7) << left << (lowMass ? "yes" : "no"); | |
913 | cout << setw(7) << left << (unlike ? "yes" : "no"); | |
914 | cout << setw(6) << left << AliHLTUInt16_t(highPtCount); | |
915 | cout << setw(8) << left << AliHLTUInt16_t(lowPtCount); | |
916 | cout << setw(0); | |
917 | ||
918 | result = CheckField(decision->fInvMass, buffer, bufferSize, continueParse); | |
919 | if (result != EXIT_SUCCESS) return result; | |
920 | cout << decision->fInvMass << endl; | |
921 | ||
922 | return EXIT_SUCCESS; | |
923 | } | |
924 | ||
925 | ||
926 | int DumpPairsDecisionBlock( | |
927 | const char* buffer, unsigned long bufferSize, | |
928 | bool continueParse | |
929 | ) | |
930 | { | |
931 | int result = EXIT_SUCCESS; | |
932 | AliHLTMUONPairsDecisionBlockReader block(buffer, bufferSize); | |
933 | ||
934 | result = CheckCommonHeader(block, buffer, bufferSize, continueParse); | |
935 | if (result != EXIT_SUCCESS and not continueParse) return result; | |
936 | ||
937 | // Dump the rest of the block header. | |
938 | const AliHLTMUONPairsDecisionBlockStruct* header = &block.BlockHeader(); | |
939 | int subResult = DumpPairsDecisionBlockHeader(buffer, bufferSize, header, continueParse); | |
940 | if (subResult != EXIT_SUCCESS) return subResult; | |
941 | ||
942 | AliHLTUInt32_t nentries = CalculateNEntries(block, bufferSize); | |
943 | ||
944 | // Print the data block record entries. | |
945 | cout << " | | Trigger Bits |" << endl; | |
946 | cout << "Track A ID | Track B ID | Raw HiMass LoMass Unlike HiPt# LoPt# | Invariant mass" << endl; | |
947 | cout << "----------------------------------------------------------------------------------------" << endl; | |
948 | const AliHLTMUONPairDecisionStruct* entry = block.GetArray(); | |
949 | for(AliHLTUInt32_t i = 0; i < nentries; i++) | |
950 | { | |
951 | subResult = DumpPairDecisionStruct(buffer, bufferSize, entry++, continueParse); | |
952 | if (subResult != EXIT_SUCCESS) return subResult; | |
953 | } | |
954 | ||
955 | return result; | |
956 | } | |
957 | ||
958 | ||
959 | int DumpCommonHeader( | |
960 | const char* buffer, unsigned long bufferSize, | |
961 | const AliHLTMUONDataBlockHeader* header, bool continueParse | |
962 | ) | |
963 | { | |
964 | // Step through the header fields trying to print them. | |
965 | // At each step check if we have not overflowed the buffer, if we have | |
966 | // not then we can print the field, otherwise we print the left over | |
967 | // bytes assumed to be corrupted rubbish. | |
968 | int result = CheckHeaderField(header->fType, buffer, bufferSize, continueParse); | |
969 | if (result != EXIT_SUCCESS) return result; | |
970 | AliHLTMUONDataBlockType type = AliHLTMUONDataBlockType(header->fType); | |
971 | cout << " Block type: " << type << endl; | |
972 | ||
973 | result = CheckHeaderField(header->fRecordWidth, buffer, bufferSize, continueParse); | |
974 | if (result != EXIT_SUCCESS) return result; | |
975 | cout << " Record width: " << header->fRecordWidth << endl; | |
976 | ||
977 | result = CheckHeaderField(header->fNrecords, buffer, bufferSize, continueParse); | |
978 | if (result != EXIT_SUCCESS) return result; | |
979 | cout << "Number of entries: " << header->fNrecords << endl; | |
980 | ||
981 | return result; | |
982 | } | |
983 | ||
984 | ||
985 | int ParseBuffer( | |
986 | const char* buffer, unsigned long bufferSize, | |
987 | bool continueParse, AliHLTMUONDataBlockType type | |
988 | ) | |
989 | { | |
990 | assert( buffer != NULL ); | |
991 | int result = EXIT_SUCCESS; | |
992 | ||
993 | if (bufferSize < sizeof(AliHLTMUONDataBlockHeader)) | |
994 | { | |
995 | cerr << "ERROR: The size of the file is too small to contain a" | |
996 | " valid data block." << endl; | |
997 | result = PARSE_ERROR; | |
998 | if (not continueParse) return result; | |
999 | } | |
1000 | const AliHLTMUONDataBlockHeader* header = | |
1001 | reinterpret_cast<const AliHLTMUONDataBlockHeader*>(buffer); | |
1002 | ||
1003 | int subResult = DumpCommonHeader(buffer, bufferSize, header, continueParse); | |
1004 | if (subResult != EXIT_SUCCESS) return subResult; | |
1005 | ||
1006 | ||
1007 | // Check if the block type in the header corresponds to the type given | |
1008 | // by the '-type' command line parameter. If they do not then print an | |
1009 | // error or big fat warning message and force interpretation of the data | |
1010 | // block with the type given by '-type'. | |
1011 | AliHLTMUONDataBlockType headerType = AliHLTMUONDataBlockType(header->fType); | |
1012 | ||
1013 | if (type == kUnknownDataBlock) | |
1014 | { | |
1015 | // -type not used in the command line so just use what is given | |
1016 | // by the data block header. | |
1017 | type = headerType; | |
1018 | } | |
1019 | else if (type != headerType) | |
1020 | { | |
1021 | cerr << "WARNING: The data block header indicates a type" | |
1022 | " different from what was specified on the command line." | |
1023 | " The data could be corrupt." | |
1024 | << endl; | |
1025 | cerr << "WARNING: The type value in the file is " | |
1026 | << showbase << hex << header->fType | |
1027 | << " (" << headerType << "), but on the command line it is " | |
1028 | << showbase << hex << int(type) << dec | |
1029 | << " (" << type << ")." | |
1030 | << endl; | |
1031 | cerr << "WARNING: Will force the interpretation of the data block" | |
1032 | " with a type of " << type << "." << endl; | |
1033 | } | |
1034 | ||
1035 | // Now we know what type the data block is supposed to be so we can | |
1036 | // dump it to screen with the appropriate dump routine. | |
1037 | switch (type) | |
1038 | { | |
1039 | case kTriggerRecordsDataBlock: | |
1040 | subResult = DumpTriggerRecordsBlock(buffer, bufferSize, continueParse); | |
1041 | if (subResult != EXIT_SUCCESS) result = subResult; | |
1042 | break; | |
1043 | case kTrigRecsDebugDataBlock: | |
1044 | subResult = DumpTrigRecsDebugBlock(buffer, bufferSize, continueParse); | |
1045 | if (subResult != EXIT_SUCCESS) result = subResult; | |
1046 | break; | |
1047 | case kTriggerChannelsDataBlock: | |
1048 | subResult = DumpTriggerChannelsBlock(buffer, bufferSize, continueParse); | |
1049 | if (subResult != EXIT_SUCCESS) result = subResult; | |
1050 | break; | |
1051 | case kRecHitsDataBlock: | |
1052 | subResult = DumpRecHitsBlock(buffer, bufferSize, continueParse); | |
1053 | if (subResult != EXIT_SUCCESS) result = subResult; | |
1054 | break; | |
1055 | case kClustersDataBlock: | |
1056 | subResult = DumpClustersBlock(buffer, bufferSize, continueParse); | |
1057 | if (subResult != EXIT_SUCCESS) result = subResult; | |
1058 | break; | |
1059 | case kChannelsDataBlock: | |
1060 | return DumpChannelsBlock(buffer, bufferSize, continueParse); | |
1061 | if (subResult != EXIT_SUCCESS) result = subResult; | |
1062 | break; | |
1063 | case kMansoTracksDataBlock: | |
1064 | subResult = DumpMansoTracksBlock(buffer, bufferSize, continueParse); | |
1065 | if (subResult != EXIT_SUCCESS) result = subResult; | |
1066 | break; | |
1067 | case kMansoCandidatesDataBlock: | |
1068 | subResult = DumpMansoCandidatesBlock(buffer, bufferSize, continueParse); | |
1069 | if (subResult != EXIT_SUCCESS) result = subResult; | |
1070 | break; | |
1071 | case kSinglesDecisionDataBlock: | |
1072 | subResult = DumpSinglesDecisionBlock(buffer, bufferSize, continueParse); | |
1073 | if (subResult != EXIT_SUCCESS) result = subResult; | |
1074 | break; | |
1075 | case kPairsDecisionDataBlock: | |
1076 | return DumpPairsDecisionBlock(buffer, bufferSize, continueParse); | |
1077 | if (subResult != EXIT_SUCCESS) result = subResult; | |
1078 | break; | |
1079 | default : | |
1080 | cout << "ERROR: Unknown data block type. Found a type number of " | |
1081 | << showbase << hex << int(type) << dec | |
1082 | << " (" << int(type) << ")." << endl; | |
1083 | result = PARSE_ERROR; | |
1084 | } | |
1085 | ||
1086 | return result; | |
1087 | } | |
1088 | ||
1089 | ||
1090 | /** | |
1091 | * The caller is responsible for freeing memory allocated for buffer with a call | |
1092 | * to delete [] buffer. | |
1093 | */ | |
1094 | int ReadFile(const char* filename, char*& buffer, unsigned long& bufferSize) | |
1095 | { | |
1096 | assert( filename != NULL ); | |
1097 | ||
1098 | // Open the file and find its size. | |
1099 | fstream file; | |
1100 | file.open(filename, ios::in); | |
1101 | if (not file) | |
1102 | { | |
1103 | cerr << "ERROR: Could not open the file: " << filename << endl; | |
1104 | return SYSTEM_ERROR; | |
1105 | } | |
1106 | file.seekg(0, ios::end); | |
1107 | if (not file) | |
1108 | { | |
1109 | cerr << "ERROR: Could not seek in the file: " << filename << endl; | |
1110 | return SYSTEM_ERROR; | |
1111 | } | |
1112 | bufferSize = file.tellg(); | |
1113 | if (not file) | |
1114 | { | |
1115 | cerr << "ERROR: Could not get file size for the file: " << | |
1116 | filename << endl; | |
1117 | return SYSTEM_ERROR; | |
1118 | } | |
1119 | file.seekg(0, ios::beg); | |
1120 | if (not file) | |
1121 | { | |
1122 | cerr << "ERROR: Could not seek in the file: " << filename << endl; | |
1123 | return SYSTEM_ERROR; | |
1124 | } | |
1125 | ||
1126 | // Allocate the memory for the file. | |
1127 | try | |
1128 | { | |
1129 | buffer = new char[bufferSize]; | |
1130 | } | |
1131 | catch (const std::bad_alloc&) | |
1132 | { | |
1133 | cerr << "ERROR: Out of memory. Tried to allocate " << bufferSize | |
1134 | << " bytes." << endl; | |
1135 | return SYSTEM_ERROR; | |
1136 | } | |
1137 | ||
1138 | file.read(buffer, bufferSize); | |
1139 | if (not file) | |
1140 | { | |
1141 | delete [] buffer; | |
1142 | buffer = NULL; | |
1143 | bufferSize = 0; | |
1144 | cerr << "ERROR: Could not read from file: " << filename << endl; | |
1145 | return SYSTEM_ERROR; | |
1146 | } | |
1147 | ||
1148 | file.close(); | |
1149 | if (not file) | |
1150 | { | |
1151 | delete [] buffer; | |
1152 | buffer = NULL; | |
1153 | bufferSize = 0; | |
1154 | cerr << "ERROR: Could not close the file: " << filename << endl; | |
1155 | return SYSTEM_ERROR; | |
1156 | } | |
1157 | ||
1158 | return EXIT_SUCCESS; | |
1159 | } | |
1160 | ||
1161 | /** | |
1162 | * Prints the command line usage of this program to standard error. | |
1163 | */ | |
1164 | void PrintUsage() | |
1165 | { | |
1166 | cerr << "Usage: dHLTdumpraw [-help|-h] [-continue] [-type <typename>] <filename>" << endl; | |
1167 | cerr << "Where <filename> is the name of a file containing a raw data block." << endl; | |
1168 | cerr << "Options:" << endl; | |
1169 | cerr << " -help | -h" << endl; | |
1170 | cerr << " Displays this message." << endl; | |
1171 | cerr << " -continue" << endl; | |
1172 | cerr << " If specified, the program will try to continue parsing the data block" << endl; | |
1173 | cerr << " as much as possible rather than stopping at the first error." << endl; | |
1174 | cerr << " -type <typename>" << endl; | |
1175 | cerr << " Forces the contents of the file to be interpreted as a specific" << endl; | |
1176 | cerr << " type of data block. Where <typename> can be one of:" << endl; | |
1177 | cerr << " trigrecs - trigger records data." << endl; | |
1178 | cerr << " trigrecsdebug - debugging information about trigger records." << endl; | |
1179 | cerr << " trigchannels - channel debugging in." << endl; | |
1180 | cerr << " rechits - reconstructed hits data." << endl; | |
1181 | cerr << " channels - channel debugging information from hit reconstruction." << endl; | |
1182 | cerr << " clusters - cluster debugging information from hit reconstruction." << endl; | |
1183 | cerr << " mansotracks - partial tracks from Manso algorithm." << endl; | |
1184 | cerr << " mansocandidates - track candidates considered in the Manso algorithm." << endl; | |
1185 | cerr << " singlesdecision - trigger decisions for single tracks." << endl; | |
1186 | cerr << " pairsdecision - trigger decisions for track pairs." << endl; | |
1187 | } | |
1188 | ||
1189 | /** | |
1190 | * Parse the string passed as the type of the block and return the corresponding | |
1191 | * AliHLTMUONDataBlockType value. | |
1192 | */ | |
1193 | AliHLTMUONDataBlockType ParseCommandLineType(const char* type) | |
1194 | { | |
1195 | if (strcmp(type, "trigrecs") == 0) | |
1196 | { | |
1197 | return kTriggerRecordsDataBlock; | |
1198 | } | |
1199 | else if (strcmp(type, "trigrecsdebug") == 0) | |
1200 | { | |
1201 | return kTrigRecsDebugDataBlock; | |
1202 | } | |
1203 | else if (strcmp(type, "trigchannels") == 0) | |
1204 | { | |
1205 | return kTriggerChannelsDataBlock; | |
1206 | } | |
1207 | else if (strcmp(type, "rechits") == 0) | |
1208 | { | |
1209 | return kRecHitsDataBlock; | |
1210 | } | |
1211 | else if (strcmp(type,"channels") == 0) | |
1212 | { | |
1213 | return kChannelsDataBlock; | |
1214 | } | |
1215 | else if (strcmp(type,"clusters") == 0) | |
1216 | { | |
1217 | return kClustersDataBlock; | |
1218 | } | |
1219 | else if (strcmp(type, "mansotracks") == 0) | |
1220 | { | |
1221 | return kMansoTracksDataBlock; | |
1222 | } | |
1223 | else if (strcmp(type, "mansocandidates") == 0) | |
1224 | { | |
1225 | return kMansoCandidatesDataBlock; | |
1226 | } | |
1227 | else if (strcmp(type, "singlesdecision") == 0) | |
1228 | { | |
1229 | return kSinglesDecisionDataBlock; | |
1230 | } | |
1231 | else if (strcmp(type, "pairsdecision") == 0) | |
1232 | { | |
1233 | return kPairsDecisionDataBlock; | |
1234 | } | |
1235 | ||
1236 | cerr << "ERROR: Invalid type name '" << type << "' specified for argument -type." | |
1237 | << endl << endl; | |
1238 | PrintUsage(); | |
1239 | return kUnknownDataBlock; | |
1240 | } | |
1241 | ||
1242 | /** | |
1243 | * Parses the command line. | |
1244 | * @param argc Number of arguments as given in main(). | |
1245 | * @param argv Array of arguments as given in main(). | |
1246 | * @param filename Receives the pointer to the file name string. | |
1247 | * @param type Receives the type of the data block expected, i.e. the | |
1248 | * value of the -type flag. | |
1249 | * @return A status flag suitable for returning from main(), containing either | |
1250 | * EXIT_SUCCESS or CMDLINE_ERROR. | |
1251 | */ | |
1252 | int ParseCommandLine( | |
1253 | int argc, const char** argv, | |
1254 | const char*& filename, bool& continueParse, | |
1255 | AliHLTMUONDataBlockType& type | |
1256 | ) | |
1257 | { | |
1258 | filename = NULL; | |
1259 | continueParse = false; | |
1260 | ||
1261 | // Parse the command line. | |
1262 | for (int i = 1; i < argc; i++) | |
1263 | { | |
1264 | if (strcmp(argv[i], "-help") == 0 || strcmp(argv[i], "-h") == 0) | |
1265 | { | |
1266 | PrintUsage(); | |
1267 | return EXIT_SUCCESS; | |
1268 | } | |
1269 | else if (strcmp(argv[i], "-continue") == 0) | |
1270 | { | |
1271 | continueParse = true; | |
1272 | } | |
1273 | else if (strcmp(argv[i], "-type") == 0) | |
1274 | { | |
1275 | // Now we need to parse the typename in the command line. | |
1276 | type = ParseCommandLineType(argv[++i]); | |
1277 | if (type == kUnknownDataBlock) return CMDLINE_ERROR; | |
1278 | } | |
1279 | else | |
1280 | { | |
1281 | if (filename != NULL) | |
1282 | { | |
1283 | cerr << "ERROR: Only one file can be specified, but got '" | |
1284 | << argv[i] << "', with '" << filename | |
1285 | << "' specified earlier." << endl << endl; | |
1286 | PrintUsage(); | |
1287 | return CMDLINE_ERROR; | |
1288 | } | |
1289 | else | |
1290 | filename = argv[i]; | |
1291 | } | |
1292 | } | |
1293 | ||
1294 | // Now check that we have the filename and all the flags we need. | |
1295 | if (filename == NULL) | |
1296 | { | |
1297 | cerr << "ERROR: Missing a file name. You must specify a file to process." | |
1298 | << endl << endl; | |
1299 | PrintUsage(); | |
1300 | return CMDLINE_ERROR; | |
1301 | } | |
1302 | ||
1303 | return EXIT_SUCCESS; | |
1304 | } | |
1305 | ||
1306 | ||
1307 | int main(int argc, const char** argv) | |
1308 | { | |
1309 | const char* filename = NULL; | |
1310 | bool continueParse = false; | |
1311 | int returnCode = EXIT_SUCCESS; | |
1312 | AliHLTMUONDataBlockType type = kUnknownDataBlock; | |
1313 | char* buffer = NULL; | |
1314 | ||
1315 | try | |
1316 | { | |
1317 | returnCode = ParseCommandLine(argc, argv, filename, continueParse, type); | |
1318 | ||
465b8fe6 | 1319 | if (returnCode == EXIT_SUCCESS and filename != NULL) |
3dad52b0 | 1320 | { |
1321 | unsigned long bufferSize = 0; | |
1322 | returnCode = ReadFile(filename, buffer, bufferSize); | |
1323 | if (returnCode == EXIT_SUCCESS) | |
1324 | returnCode = ParseBuffer(buffer, bufferSize, continueParse, type); | |
1325 | if (buffer != NULL) delete [] buffer; | |
1326 | } | |
1327 | ||
1328 | } | |
1329 | catch (...) | |
1330 | { | |
1331 | cerr << "FATAL ERROR: An unknown exception occurred!" << endl << endl; | |
1332 | returnCode = FATAL_ERROR; | |
1333 | if (buffer != NULL) delete [] buffer; | |
1334 | } | |
1335 | ||
1336 | return returnCode; | |
1337 | } |