]>
Commit | Line | Data |
---|---|---|
b0201cbe | 1 | /************************************************************************** |
ffc1a6f6 | 2 | * This file is property of and copyright by the ALICE HLT Project * |
960d54ad | 3 | * All rights reserved. * |
b0201cbe | 4 | * * |
960d54ad | 5 | * Primary Authors: * |
6 | * Indranil Das <indra.das@saha.ac.in> * | |
ffc1a6f6 | 7 | * Artur Szostak <artursz@iafrica.com> * |
b0201cbe | 8 | * * |
9 | * Permission to use, copy, modify and distribute this software and its * | |
10 | * documentation strictly for non-commercial purposes is hereby granted * | |
11 | * without fee, provided that the above copyright notice appears in all * | |
12 | * copies and that both the copyright notice and this permission notice * | |
13 | * appear in the supporting documentation. The authors make no claims * | |
ffc1a6f6 | 14 | * about the suitability of this software for any purpose. It is * |
b0201cbe | 15 | * provided "as is" without express or implied warranty. * |
16 | **************************************************************************/ | |
17 | ||
1d8ae082 | 18 | // $Id$ |
b0201cbe | 19 | |
6253e09b | 20 | /// |
ffc1a6f6 | 21 | /// @file AliHLTMUONHitReconstructorComponent.cxx |
22 | /// @author Indranil Das <indra.das@saha.ac.in> | <indra.ehep@gmail.com>, Artur Szostak <artursz@iafrica.com> | |
23 | /// @date 28 May 2007 | |
24 | /// @brief Implementation of the hit Reconstruction processing component. | |
6253e09b | 25 | /// |
26 | /// The HitRec Component is designed to deal the rawdata inputfiles to findout the | |
27 | /// the reconstructed hits. The output is send to the output block for further | |
28 | /// processing. | |
29 | /// | |
30 | /// Author : Indranil Das ( indra.das@saha.ac.in || indra.ehep@gmail.com ) | |
31 | /// | |
b0201cbe | 32 | |
960d54ad | 33 | #include "AliHLTMUONRecHitsBlockStruct.h" |
b0201cbe | 34 | #include "AliHLTMUONHitReconstructorComponent.h" |
b12fe461 | 35 | #include "AliHLTMUONHitReconstructor.h" |
960d54ad | 36 | #include "AliHLTMUONConstants.h" |
668eee9f | 37 | #include "AliHLTMUONUtils.h" |
5ff5f960 | 38 | #include "AliHLTMUONDataBlockWriter.h" |
a6b16447 | 39 | #include "AliHLTMUONHitReconstructor.h" |
b0201cbe | 40 | #include "AliHLTLogging.h" |
41 | #include "AliHLTSystem.h" | |
42 | #include "AliHLTDefinitions.h" | |
eeef69f0 | 43 | #include "AliHLTCDHWrapper.h" |
29486e5a | 44 | #include <cstdlib> |
45 | #include <cerrno> | |
46 | #include <cassert> | |
93a75941 | 47 | #include <fstream> |
b0201cbe | 48 | |
ffc1a6f6 | 49 | #include "TMap.h" |
50 | ||
51 | //STEER | |
ee3678d3 | 52 | #include "AliCDBManager.h" |
53 | #include "AliGeomManager.h" | |
54 | ||
55 | //MUON | |
56 | #include "AliMUONGeometryTransformer.h" | |
57 | #include "AliMUONCalibrationData.h" | |
58 | #include "AliMUONVCalibParam.h" | |
59 | ||
a6b16447 | 60 | //MUON/mapping |
ee3678d3 | 61 | #include "AliMpCDB.h" |
62 | #include "AliMpPad.h" | |
63 | #include "AliMpSegmentation.h" | |
64 | #include "AliMpDDLStore.h" | |
65 | #include "AliMpDEIterator.h" | |
66 | #include "AliMpVSegmentation.h" | |
67 | #include "AliMpDEManager.h" | |
68 | #include "AliMpDetElement.h" | |
69 | ||
b0201cbe | 70 | ClassImp(AliHLTMUONHitReconstructorComponent) |
71 | ||
72 | ||
29486e5a | 73 | AliHLTMUONHitReconstructorComponent::AliHLTMUONHitReconstructorComponent() : |
154cba94 | 74 | AliHLTMUONProcessor(), |
29486e5a | 75 | fHitRec(NULL), |
a6b16447 | 76 | fDDL(-1), |
93a75941 | 77 | fLutSize(0), |
78 | fLut(NULL), | |
ee3678d3 | 79 | fIdToEntry(), |
83d66053 | 80 | fMaxEntryPerBusPatch(), |
90af8855 | 81 | fWarnForUnexpecedBlock(false), |
56f0ccdf | 82 | fUseIdealGain(false), |
83 | fWarnIfPadSkipped(false) | |
b0201cbe | 84 | { |
6253e09b | 85 | /// |
86 | /// Default constructor. | |
87 | /// | |
b0201cbe | 88 | } |
89 | ||
960d54ad | 90 | |
b0201cbe | 91 | AliHLTMUONHitReconstructorComponent::~AliHLTMUONHitReconstructorComponent() |
92 | { | |
6253e09b | 93 | /// |
94 | /// Default destructor. | |
95 | /// | |
ee3678d3 | 96 | |
97 | if (fHitRec != NULL) | |
98 | { | |
99 | delete fHitRec; | |
100 | } | |
93a75941 | 101 | if (fLut != NULL) |
102 | { | |
878cb83d | 103 | delete [] fLut; |
93a75941 | 104 | } |
960d54ad | 105 | } |
b0201cbe | 106 | |
960d54ad | 107 | const char* AliHLTMUONHitReconstructorComponent::GetComponentID() |
108 | { | |
6253e09b | 109 | /// |
110 | /// Inherited from AliHLTComponent. Returns the component ID. | |
111 | /// | |
112 | ||
29486e5a | 113 | return AliHLTMUONConstants::HitReconstructorId(); |
b0201cbe | 114 | } |
115 | ||
b0201cbe | 116 | |
ffb64d3e | 117 | void AliHLTMUONHitReconstructorComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list) |
960d54ad | 118 | { |
6253e09b | 119 | /// |
120 | /// Inherited from AliHLTProcessor. Returns the list of expected input data types. | |
121 | /// | |
122 | ||
29486e5a | 123 | list.clear(); |
668eee9f | 124 | list.push_back( AliHLTMUONConstants::DDLRawDataType() ); |
960d54ad | 125 | } |
b0201cbe | 126 | |
b0201cbe | 127 | |
960d54ad | 128 | AliHLTComponentDataType AliHLTMUONHitReconstructorComponent::GetOutputDataType() |
129 | { | |
6253e09b | 130 | /// |
131 | /// Inherited from AliHLTComponent. Returns the output data type. | |
132 | /// | |
133 | ||
4d76a068 | 134 | return kAliHLTMultipleDataType; |
135 | } | |
136 | ||
137 | ||
138 | int AliHLTMUONHitReconstructorComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& list) | |
139 | { | |
140 | /// Inherited from AliHLTComponent. Returns the output data types. | |
141 | ||
142 | assert( list.empty() ); | |
143 | list.push_back( AliHLTMUONConstants::RecHitsBlockDataType() ); | |
144 | list.push_back( AliHLTMUONConstants::ClusterBlockDataType() ); | |
145 | list.push_back( AliHLTMUONConstants::ChannelBlockDataType() ); | |
146 | return list.size(); | |
960d54ad | 147 | } |
b0201cbe | 148 | |
b0201cbe | 149 | |
ffb64d3e | 150 | void AliHLTMUONHitReconstructorComponent::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier) |
960d54ad | 151 | { |
6253e09b | 152 | /// |
153 | /// Inherited from AliHLTComponent. Returns an estimate of the expected output data size. | |
154 | /// | |
155 | ||
979076f8 | 156 | constBase = sizeof(AliHLTMUONRecHitsBlockWriter::HeaderType) + 1024*1024; |
29486e5a | 157 | inputMultiplier = 1; |
960d54ad | 158 | } |
b0201cbe | 159 | |
b0201cbe | 160 | |
960d54ad | 161 | AliHLTComponent* AliHLTMUONHitReconstructorComponent::Spawn() |
162 | { | |
6253e09b | 163 | /// |
164 | /// Inherited from AliHLTComponent. Creates a new object instance. | |
165 | /// | |
166 | ||
29486e5a | 167 | return new AliHLTMUONHitReconstructorComponent; |
960d54ad | 168 | } |
b0201cbe | 169 | |
b0201cbe | 170 | |
29486e5a | 171 | int AliHLTMUONHitReconstructorComponent::DoInit(int argc, const char** argv) |
960d54ad | 172 | { |
6253e09b | 173 | /// |
174 | /// Inherited from AliHLTComponent. | |
175 | /// Parses the command line parameters and initialises the component. | |
176 | /// | |
b0201cbe | 177 | |
ee3678d3 | 178 | HLTInfo("Initialising dHLT hit reconstruction component."); |
ffb64d3e | 179 | |
180 | // Inherit the parents functionality. | |
181 | int result = AliHLTMUONProcessor::DoInit(argc, argv); | |
182 | if (result != 0) return result; | |
960d54ad | 183 | |
93a75941 | 184 | // Must make sure that fHitRec and fLut is deleted if it is still |
185 | // allocated for whatever reason. | |
a6b16447 | 186 | FreeMemory(); |
187 | ||
a6b16447 | 188 | // Initialise fields with default values then parse the command line. |
189 | fDDL = -1; | |
190 | fIdToEntry.clear(); | |
83d66053 | 191 | fMaxEntryPerBusPatch.clear(); |
ee3678d3 | 192 | fWarnForUnexpecedBlock = false; |
90af8855 | 193 | fUseIdealGain = false; |
56f0ccdf | 194 | fWarnIfPadSkipped = false; |
ee3678d3 | 195 | const char* lutFileName = NULL; |
ee3678d3 | 196 | bool useCDB = false; |
a9afae73 | 197 | typedef AliHLTMUONHitReconstructor HR; |
198 | HR::ERecoveryMode recoveryMode = HR::kDontTryRecover; | |
ffc1a6f6 | 199 | AliHLTInt32_t dccut = -1; |
a9afae73 | 200 | bool skipParityErrors = false; |
201 | bool dontPrintParityErrors = false; | |
83d66053 | 202 | bool makeClusters = false; |
203 | bool makeChannels = false; | |
ee3678d3 | 204 | |
205 | for (int i = 0; i < argc; i++) | |
206 | { | |
ffb64d3e | 207 | // To keep the legacy behaviour we need to have the following check |
208 | // for -cdbpath here, before ArgumentAlreadyHandled. | |
209 | if (strcmp(argv[i], "-cdbpath") == 0) | |
210 | { | |
211 | useCDB = true; | |
212 | } | |
213 | ||
214 | if (ArgumentAlreadyHandled(i, argv[i])) continue; | |
ee3678d3 | 215 | |
216 | if (strcmp( argv[i], "-ddl" ) == 0) | |
217 | { | |
ffc1a6f6 | 218 | if (fDDL != -1) |
219 | { | |
220 | HLTWarning("DDL number was already specified." | |
221 | " Will replace previous value given by -ddl or -ddlid." | |
222 | ); | |
223 | } | |
224 | ||
ee3678d3 | 225 | if (argc <= i+1) |
226 | { | |
f064ef44 | 227 | HLTError("The DDL number was not specified. Must be in the range [1..20]."); |
a6b16447 | 228 | return -EINVAL; |
ee3678d3 | 229 | } |
230 | ||
231 | char* cpErr = NULL; | |
232 | unsigned long num = strtoul( argv[i+1], &cpErr, 0 ); | |
233 | if (cpErr == NULL or *cpErr != '\0') | |
234 | { | |
93a75941 | 235 | HLTError("Cannot convert '%s' to DDL a number.", argv[i+1] ); |
a6b16447 | 236 | return -EINVAL; |
ee3678d3 | 237 | } |
f064ef44 | 238 | if (num < 1 or 20 < num) |
ee3678d3 | 239 | { |
f064ef44 | 240 | HLTError("The DDL number must be in the range [1..20]."); |
a6b16447 | 241 | return -EINVAL; |
ee3678d3 | 242 | } |
f064ef44 | 243 | fDDL = num - 1; // convert to range [0..19] |
ee3678d3 | 244 | |
245 | i++; | |
246 | continue; | |
247 | } // -ddl argument | |
248 | ||
a3d4b6ba | 249 | if (strcmp( argv[i], "-ddlid" ) == 0) |
250 | { | |
ffc1a6f6 | 251 | if (fDDL != -1) |
252 | { | |
253 | HLTWarning("DDL number was already specified." | |
254 | " Will replace previous value given by -ddl or -ddlid." | |
255 | ); | |
256 | } | |
257 | ||
a3d4b6ba | 258 | if ( argc <= i+1 ) |
259 | { | |
f064ef44 | 260 | HLTError("DDL equipment ID number not specified. It must be in the range [2560..2579]" ); |
a3d4b6ba | 261 | return -EINVAL; |
262 | } | |
263 | ||
264 | char* cpErr = NULL; | |
265 | unsigned long num = strtoul(argv[i+1], &cpErr, 0); | |
266 | if (cpErr == NULL or *cpErr != '\0') | |
267 | { | |
268 | HLTError("Cannot convert '%s' to a DDL equipment ID Number.", argv[i+1]); | |
a3d4b6ba | 269 | return -EINVAL; |
270 | } | |
271 | fDDL = AliHLTMUONUtils::EquipIdToDDLNumber(num); // Convert to DDL number in the range 0..21 | |
f064ef44 | 272 | if (fDDL < 0 or 19 < fDDL) |
a3d4b6ba | 273 | { |
f064ef44 | 274 | HLTError("The DDL equipment ID number must be in the range [2560..2579]."); |
a3d4b6ba | 275 | return -EINVAL; |
276 | } | |
277 | ||
278 | i++; | |
279 | continue; | |
280 | } | |
281 | ||
ee3678d3 | 282 | if (strcmp( argv[i], "-lut" ) == 0) |
283 | { | |
ffc1a6f6 | 284 | if (lutFileName != NULL) |
285 | { | |
286 | HLTWarning("LUT path was already specified." | |
287 | " Will replace previous value given by -lut." | |
288 | ); | |
289 | } | |
290 | ||
ee3678d3 | 291 | if (argc <= i+1) |
292 | { | |
293 | HLTError("The lookup table filename was not specified."); | |
a6b16447 | 294 | return -EINVAL; |
ee3678d3 | 295 | } |
296 | lutFileName = argv[i+1]; | |
297 | i++; | |
298 | continue; | |
299 | } // -lut argument | |
300 | ||
301 | if (strcmp( argv[i], "-cdb" ) == 0) | |
302 | { | |
303 | useCDB = true; | |
304 | continue; | |
305 | } // -cdb argument | |
306 | ||
ffc1a6f6 | 307 | if (strcmp( argv[i], "-dccut" ) == 0) |
308 | { | |
309 | if (dccut != -1) | |
310 | { | |
311 | HLTWarning("DC cut parameter was already specified." | |
312 | " Will replace previous value given by -dccut." | |
313 | ); | |
314 | } | |
315 | ||
316 | if ( argc <= i+1 ) | |
317 | { | |
318 | HLTError("No DC cut value was specified. It should be a positive integer value." ); | |
ffc1a6f6 | 319 | return -EINVAL; |
320 | } | |
321 | ||
322 | char* cpErr = NULL; | |
323 | dccut = AliHLTInt32_t( strtol(argv[i+1], &cpErr, 0) ); | |
324 | if (cpErr == NULL or *cpErr != '\0' or dccut < 0) | |
325 | { | |
326 | HLTError("Cannot convert '%s' to a valid DC cut value." | |
327 | " Expected a positive integer value.", argv[i+1] | |
328 | ); | |
ffc1a6f6 | 329 | return -EINVAL; |
330 | } | |
331 | ||
332 | i++; | |
333 | continue; | |
334 | } | |
335 | ||
ee3678d3 | 336 | if (strcmp( argv[i], "-warn_on_unexpected_block" ) == 0) |
337 | { | |
338 | fWarnForUnexpecedBlock = true; | |
339 | continue; | |
340 | } | |
a5d4696f | 341 | |
342 | if (strcmp( argv[i], "-tryrecover" ) == 0) | |
343 | { | |
a9afae73 | 344 | if (argc > i+1) |
345 | { | |
346 | // There might be an optional parameter so check | |
347 | // if it is a recognised one. If not then assume it | |
348 | // is the next argument, so no error message. | |
349 | if (strcmp(argv[i+1], "full") == 0) | |
350 | { | |
351 | recoveryMode = HR::kRecoverFull; | |
352 | i++; | |
353 | } | |
354 | else if (strcmp(argv[i+1], "skip") == 0) | |
355 | { | |
356 | recoveryMode = HR::kRecoverJustSkip; | |
357 | i++; | |
358 | } | |
359 | else if (strcmp(argv[i+1], "parityerrors") == 0) | |
360 | { | |
361 | recoveryMode = HR::kRecoverFromParityErrorsOnly; | |
362 | i++; | |
363 | } | |
364 | else | |
365 | { | |
366 | recoveryMode = HR::kRecoverFull; | |
367 | } | |
368 | } | |
369 | else | |
370 | { | |
371 | recoveryMode = HR::kRecoverFull; | |
372 | } | |
373 | continue; | |
374 | } | |
375 | ||
376 | if (strcmp( argv[i], "-skipparityerrors" ) == 0) | |
377 | { | |
378 | skipParityErrors = true; | |
379 | continue; | |
380 | } | |
381 | ||
382 | if (strcmp( argv[i], "-dontprintparityerrors" ) == 0) | |
383 | { | |
384 | dontPrintParityErrors = true; | |
a5d4696f | 385 | continue; |
386 | } | |
90af8855 | 387 | |
388 | if (strcmp( argv[i], "-useidealgain" ) == 0) | |
389 | { | |
390 | fUseIdealGain = true; | |
391 | continue; | |
392 | } | |
83d66053 | 393 | |
394 | if (strcmp( argv[i], "-makeclusters" ) == 0) | |
395 | { | |
396 | makeClusters = true; | |
397 | continue; | |
398 | } | |
399 | ||
400 | if (strcmp( argv[i], "-makechannels" ) == 0) | |
401 | { | |
402 | makeChannels = true; | |
403 | continue; | |
404 | } | |
56f0ccdf | 405 | |
406 | if (strcmp( argv[i], "-warnifpadskipped" ) == 0) | |
407 | { | |
408 | fWarnIfPadSkipped = true; | |
409 | continue; | |
410 | } | |
ee3678d3 | 411 | |
412 | HLTError("Unknown option '%s'", argv[i]); | |
a6b16447 | 413 | return -EINVAL; |
ee3678d3 | 414 | |
415 | } // for loop | |
416 | ||
ffb64d3e | 417 | try |
418 | { | |
419 | fHitRec = new AliHLTMUONHitReconstructor(); | |
420 | } | |
421 | catch (const std::bad_alloc&) | |
422 | { | |
423 | HLTError("Could not allocate more memory for the hit reconstructor component."); | |
424 | return -ENOMEM; | |
425 | } | |
426 | ||
2b7af22a | 427 | if (dccut != -1 and useCDB) |
428 | { | |
429 | HLTWarning("The -cdb or -cdbpath parameter was specified, which indicates that" | |
430 | " this component should read from the CDB, but then the -dccut argument" | |
431 | " was also used. Will override the value from CDB with the command" | |
432 | " line DC cut parameter given." | |
433 | ); | |
434 | } | |
435 | ||
436 | if (lutFileName != NULL and useCDB == true) | |
437 | { | |
438 | HLTWarning("The -cdb or -cdbpath parameter was specified, which indicates that" | |
439 | " this component should read from the CDB, but then the -lut argument" | |
440 | " was also used. Will ignore the -lut option and load from CDB anyway." | |
441 | ); | |
442 | } | |
443 | ||
93a75941 | 444 | if (lutFileName == NULL) useCDB = true; |
445 | ||
ffb64d3e | 446 | if (fDDL == -1 and not DelaySetup()) |
a6b16447 | 447 | { |
448 | HLTWarning("DDL number not specified. Cannot check if incomming data is valid."); | |
449 | } | |
450 | ||
ee3678d3 | 451 | if (useCDB) |
452 | { | |
ffb64d3e | 453 | if (not DelaySetup()) |
ffc1a6f6 | 454 | { |
455 | HLTInfo("Loading lookup table information from CDB for DDL %d (ID = %d).", | |
456 | fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL) | |
457 | ); | |
4e22efc4 | 458 | result = ReadLutFromCDB(); |
ffc1a6f6 | 459 | if (result != 0) |
460 | { | |
461 | // Error messages already generated in ReadLutFromCDB. | |
462 | FreeMemory(); // Make sure we cleanup to avoid partial initialisation. | |
463 | return result; | |
464 | } | |
83d66053 | 465 | fHitRec->SetLookUpTable(fLut, &fIdToEntry, &fMaxEntryPerBusPatch); |
ffc1a6f6 | 466 | } |
960d54ad | 467 | } |
ee3678d3 | 468 | else |
469 | { | |
93a75941 | 470 | HLTInfo("Loading lookup table information from file %s.", lutFileName); |
4e22efc4 | 471 | result = ReadLookUpTable(lutFileName); |
ffc1a6f6 | 472 | if (result != 0) |
473 | { | |
474 | // Error messages already generated in ReadLookUpTable. | |
475 | FreeMemory(); // Make sure we cleanup to avoid partial initialisation. | |
476 | return result; | |
477 | } | |
83d66053 | 478 | fHitRec->SetLookUpTable(fLut, &fIdToEntry, &fMaxEntryPerBusPatch); |
ee3678d3 | 479 | } |
ffc1a6f6 | 480 | |
481 | if (dccut == -1) | |
ee3678d3 | 482 | { |
ffb64d3e | 483 | if (not DelaySetup()) |
ffc1a6f6 | 484 | { |
485 | HLTInfo("Loading DC cut parameters from CDB for DDL %d (ID = %d).", | |
486 | fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL) | |
487 | ); | |
4e22efc4 | 488 | result = ReadDCCutFromCDB(); |
ffc1a6f6 | 489 | if (result != 0) |
490 | { | |
491 | // Error messages already generated in ReadDCCutFromCDB. | |
492 | FreeMemory(); // Make sure we cleanup to avoid partial initialisation. | |
493 | return result; | |
494 | } | |
2b7af22a | 495 | } |
496 | else | |
497 | { | |
498 | // Print the debug messages here since ReadDCCutFromCDB does not get called, | |
499 | // in-which the debug messages would have been printed. | |
ffc1a6f6 | 500 | HLTDebug("Using DC cut parameter of %d ADC channels.", fHitRec->GetDCCut()); |
501 | } | |
502 | } | |
503 | else | |
504 | { | |
ffc1a6f6 | 505 | fHitRec->SetDCCut(dccut); |
506 | HLTDebug("Using DC cut parameter of %d ADC channels.", fHitRec->GetDCCut()); | |
ee3678d3 | 507 | } |
508 | ||
a9afae73 | 509 | fHitRec->TryRecover(recoveryMode); |
510 | fHitRec->SkipParityErrors(skipParityErrors); | |
511 | fHitRec->DontPrintParityErrors(dontPrintParityErrors); | |
83d66053 | 512 | fHitRec->GenerateClusterInfo(makeClusters); |
513 | fHitRec->GenerateChannelInfo(makeChannels); | |
514 | fHitRec->DDLNumber(fDDL); | |
fd5b812e | 515 | //The DDL number has to be set before the following InitDetElemInDDLArray() method |
516 | fHitRec->InitDetElemInDDLArray(); | |
90af8855 | 517 | HLTDebug("dHLT hit reconstruction component is initialized."); |
ee3678d3 | 518 | return 0; |
b0201cbe | 519 | } |
520 | ||
960d54ad | 521 | |
522 | int AliHLTMUONHitReconstructorComponent::DoDeinit() | |
523 | { | |
6253e09b | 524 | /// |
525 | /// Inherited from AliHLTComponent. Performs a cleanup of the component. | |
526 | /// | |
fd5b812e | 527 | fHitRec->DeInitDetElemInDDLArray(); |
ee3678d3 | 528 | HLTInfo("Deinitialising dHLT hit reconstruction component."); |
a6b16447 | 529 | FreeMemory(); |
ee3678d3 | 530 | return 0; |
b0201cbe | 531 | } |
532 | ||
b0201cbe | 533 | |
ffc1a6f6 | 534 | int AliHLTMUONHitReconstructorComponent::Reconfigure( |
535 | const char* cdbEntry, const char* componentId | |
536 | ) | |
537 | { | |
538 | /// Inherited from AliHLTComponent. This method will reload CDB configuration | |
539 | /// entries for this component from the CDB. | |
540 | /// \param cdbEntry If this is NULL then it is assumed that all CDB entries should | |
541 | /// be reloaded. Otherwise a particular value for 'cdbEntry' will trigger | |
542 | /// reloading of the LUT if the path contains 'MUON/' and reloading of the DC | |
2b7af22a | 543 | /// cut parameter if 'cdbEntry' equals "HLT/ConfigMUON/HitReconstructor". |
544 | /// \param componentId The name of the component in the current chain. | |
545 | ||
ad9d297e | 546 | TString path = cdbEntry; |
547 | bool startsWithMUON = path.Index("MUON/", 5, 0, TString::kExact) == 0; | |
548 | bool givenConfigPath = (path == AliHLTMUONConstants::HitReconstructorCDBPath()); | |
ffc1a6f6 | 549 | |
2b7af22a | 550 | if (cdbEntry == NULL or startsWithMUON or givenConfigPath) |
ffc1a6f6 | 551 | { |
2b7af22a | 552 | HLTInfo("Reading new configuration entries from CDB for component '%s'.", componentId); |
553 | } | |
ffc1a6f6 | 554 | |
2b7af22a | 555 | if (cdbEntry == NULL or startsWithMUON) |
556 | { | |
557 | // First clear the current LUT data and then load in the new values. | |
558 | if (fLut != NULL) | |
ffc1a6f6 | 559 | { |
2b7af22a | 560 | delete [] fLut; |
561 | fLut = NULL; | |
562 | fLutSize = 0; | |
ffc1a6f6 | 563 | } |
564 | ||
2b7af22a | 565 | fIdToEntry.clear(); |
83d66053 | 566 | fMaxEntryPerBusPatch.clear(); |
2b7af22a | 567 | int result = ReadLutFromCDB(); |
568 | if (result != 0) return result; | |
83d66053 | 569 | fHitRec->SetLookUpTable(fLut, &fIdToEntry, &fMaxEntryPerBusPatch); |
2b7af22a | 570 | } |
571 | ||
572 | if (cdbEntry == NULL or not startsWithMUON) | |
573 | { | |
574 | int result = ReadDCCutFromCDB(); | |
575 | if (result != 0) return result; | |
ffc1a6f6 | 576 | } |
577 | ||
578 | return 0; | |
579 | } | |
580 | ||
581 | ||
582 | int AliHLTMUONHitReconstructorComponent::ReadPreprocessorValues(const char* modules) | |
583 | { | |
584 | /// Inherited from AliHLTComponent. | |
585 | /// Updates the configuration of this component if either HLT or MUON have | |
586 | /// been specified in the 'modules' list. | |
587 | ||
588 | TString mods = modules; | |
589 | if (mods.Contains("ALL") or (mods.Contains("HLT") and mods.Contains("MUON"))) | |
590 | { | |
591 | return Reconfigure(NULL, GetComponentID()); | |
592 | } | |
593 | if (mods.Contains("HLT")) | |
594 | { | |
595 | return Reconfigure(AliHLTMUONConstants::HitReconstructorCDBPath(), GetComponentID()); | |
596 | } | |
597 | if (mods.Contains("MUON")) | |
598 | { | |
599 | return Reconfigure("MUON/*", GetComponentID()); | |
600 | } | |
601 | return 0; | |
602 | } | |
603 | ||
604 | ||
960d54ad | 605 | int AliHLTMUONHitReconstructorComponent::DoEvent( |
606 | const AliHLTComponentEventData& evtData, | |
b8d467da | 607 | const AliHLTComponentBlockData* blocks, |
ffb64d3e | 608 | AliHLTComponentTriggerData& trigData, |
b8d467da | 609 | AliHLTUInt8_t* outputPtr, |
960d54ad | 610 | AliHLTUInt32_t& size, |
ffb64d3e | 611 | AliHLTComponentBlockDataList& outputBlocks |
960d54ad | 612 | ) |
613 | { | |
6253e09b | 614 | /// |
615 | /// Inherited from AliHLTProcessor. Processes the new event data. | |
616 | /// | |
ffb64d3e | 617 | |
ffc1a6f6 | 618 | // Initialise the LUT and DC cut parameter from CDB if we were requested |
619 | // to initialise only when the first event was received. | |
ffb64d3e | 620 | if (DelaySetup()) |
ffc1a6f6 | 621 | { |
622 | // Use the specification given by the first data block if we | |
623 | // have not been given a DDL number on the command line. | |
624 | if (fDDL == -1) | |
625 | { | |
48ccb241 | 626 | bool blockFound = false; |
627 | for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt and not blockFound; n++) | |
628 | { | |
629 | if (blocks[n].fDataType != AliHLTMUONConstants::DDLRawDataType()) continue; | |
630 | blockFound = true; | |
631 | ||
632 | fDDL = AliHLTMUONUtils::SpecToDDLNumber(blocks[n].fSpecification); | |
633 | ||
634 | if (fDDL == -1) | |
635 | { | |
636 | HLTError("Received a data block with a specification (0x%8.8X)" | |
637 | " indicating multiple DDL data sources, but we must only" | |
638 | " receive raw DDL data from one tracking station DDL.", | |
639 | blocks[n].fSpecification | |
640 | ); | |
641 | return -EPROTO; | |
642 | } | |
643 | } | |
644 | ||
645 | if (not blockFound) | |
ffc1a6f6 | 646 | { |
647 | HLTError("The initialisation from CDB of the component has" | |
648 | " been delayed to the first received event. However," | |
48ccb241 | 649 | " no raw DDL data blocks have been found in the first event." |
ffc1a6f6 | 650 | ); |
651 | return -ENOENT; | |
652 | } | |
ffc1a6f6 | 653 | } |
654 | ||
655 | // Check that the LUT was not already loaded in DoInit. | |
656 | if (fLut == NULL) | |
657 | { | |
658 | HLTInfo("Loading lookup table information from CDB for DDL %d (ID = %d).", | |
659 | fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL) | |
660 | ); | |
661 | int result = ReadLutFromCDB(); | |
662 | if (result != 0) return result; | |
663 | ||
83d66053 | 664 | fHitRec->SetLookUpTable(fLut, &fIdToEntry, &fMaxEntryPerBusPatch); |
ffc1a6f6 | 665 | } |
666 | ||
667 | // Check that the DC cut was not already loaded in DoInit. | |
668 | if (fHitRec->GetDCCut() == -1) | |
669 | { | |
670 | HLTInfo("Loading DC cut parameters from CDB for DDL %d (ID = %d).", | |
671 | fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL) | |
672 | ); | |
673 | int result = ReadDCCutFromCDB(); | |
674 | if (result != 0) return result; | |
ffc1a6f6 | 675 | } |
676 | ||
ffb64d3e | 677 | DoneDelayedSetup(); |
ffc1a6f6 | 678 | } |
679 | ||
680 | if (fLut == NULL) | |
681 | { | |
682 | HLTFatal("Lookup table not loaded! Cannot continue processing data."); | |
683 | return -ENOENT; | |
684 | } | |
685 | ||
29486e5a | 686 | // Process an event |
687 | unsigned long totalSize = 0; // Amount of memory currently consumed in bytes. | |
b0201cbe | 688 | |
29486e5a | 689 | HLTDebug("Processing event %llu with %u input data blocks.", |
690 | evtData.fEventID, evtData.fBlockCnt | |
691 | ); | |
692 | ||
693 | // Loop over all input blocks in the event | |
450e0b36 | 694 | for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++) |
5ff5f960 | 695 | { |
450e0b36 | 696 | HLTDebug("Handling block: %u, with fDataType = '%s', fPtr = %p and fSize = %u bytes.", |
697 | n, DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fPtr, blocks[n].fSize | |
5ff5f960 | 698 | ); |
29486e5a | 699 | |
668eee9f | 700 | if (blocks[n].fDataType != AliHLTMUONConstants::DDLRawDataType() |
701 | or not AliHLTMUONUtils::IsTrackerDDL(blocks[n].fSpecification) | |
702 | ) | |
29486e5a | 703 | { |
704 | // Log a message indicating that we got a data block that we | |
705 | // do not know how to handle. | |
29486e5a | 706 | if (fWarnForUnexpecedBlock) |
450e0b36 | 707 | HLTWarning("Received a data block of a type we cannot handle: '%s', spec: 0x%X", |
708 | DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification | |
29486e5a | 709 | ); |
4e22efc4 | 710 | #ifdef __DEBUG |
29486e5a | 711 | else |
450e0b36 | 712 | HLTDebug("Received a data block of a type we cannot handle: '%s', spec: 0x%X", |
713 | DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification | |
29486e5a | 714 | ); |
4e22efc4 | 715 | #endif |
29486e5a | 716 | |
717 | continue; | |
718 | } | |
719 | ||
a6b16447 | 720 | if (fDDL != -1) |
ee3678d3 | 721 | { |
a3d4b6ba | 722 | AliHLTInt32_t receivedDDL = AliHLTMUONUtils::SpecToDDLNumber(blocks[n].fSpecification); |
723 | if (receivedDDL != fDDL) | |
a6b16447 | 724 | { |
a3d4b6ba | 725 | HLTWarning("Received raw data from DDL %d (ID = %d)," |
726 | " but expect data only from DDL %d (ID = %d).", | |
727 | receivedDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(receivedDDL), | |
728 | fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL) | |
729 | ); | |
a6b16447 | 730 | } |
ee3678d3 | 731 | } |
732 | ||
29486e5a | 733 | // Create a new output data block and initialise the header. |
734 | AliHLTMUONRecHitsBlockWriter block(outputPtr+totalSize, size-totalSize); | |
735 | if (not block.InitCommonHeader()) | |
736 | { | |
8bade2be | 737 | HLTError("There is not enough space in the output buffer for the new data block." |
29486e5a | 738 | " We require at least %u bytes, but have %u bytes left.", |
739 | sizeof(AliHLTMUONRecHitsBlockWriter::HeaderType), | |
740 | block.BufferSize() | |
741 | ); | |
742 | break; | |
743 | } | |
744 | ||
eeef69f0 | 745 | AliHLTCDHWrapper cdh(blocks[n].fPtr); |
746 | ||
747 | AliHLTUInt32_t headerSize = cdh.GetHeaderSize(); | |
748 | ||
29486e5a | 749 | AliHLTUInt32_t totalDDLSize = blocks[n].fSize / sizeof(AliHLTUInt32_t); |
eeef69f0 | 750 | AliHLTUInt32_t ddlRawDataSize = totalDDLSize - headerSize / sizeof(AliHLTUInt32_t); |
3240b3ce | 751 | AliHLTUInt32_t* buffer = reinterpret_cast<AliHLTUInt32_t*>(blocks[n].fPtr) |
eeef69f0 | 752 | + headerSize/sizeof(AliHLTUInt32_t); |
29486e5a | 753 | AliHLTUInt32_t nofHit = block.MaxNumberOfEntries(); |
754 | ||
ee3678d3 | 755 | #ifdef DEBUG |
29486e5a | 756 | HLTDebug("=========== Dumping DDL payload buffer =========="); |
757 | for (AliHLTUInt32_t j = 0; j < totalDDLSize; j++) | |
758 | HLTDebug("buffer[%d] : %x",j,buffer[j]); | |
759 | HLTDebug("================== End of dump ================="); | |
ee3678d3 | 760 | #endif // DEBUG |
29486e5a | 761 | |
762 | if (not fHitRec->Run(buffer, ddlRawDataSize, block.GetArray(), nofHit)) | |
763 | { | |
154cba94 | 764 | HLTError("Error while processing the hit reconstruction algorithm."); |
ffb64d3e | 765 | if (DumpDataOnError()) DumpEvent(evtData, blocks, trigData, outputPtr, size, outputBlocks); |
29486e5a | 766 | size = totalSize; // Must tell the framework how much buffer space was used. |
a6b16447 | 767 | return -EIO; |
29486e5a | 768 | } |
769 | ||
770 | // nofHit should now contain the number of reconstructed hits actually found | |
771 | // and filled into the output data block, so we can set this number. | |
772 | assert( nofHit <= block.MaxNumberOfEntries() ); | |
773 | block.SetNumberOfEntries(nofHit); | |
774 | ||
775 | HLTDebug("Number of reconstructed hits found is %d", nofHit); | |
776 | ||
777 | // Fill a block data structure for our output block. | |
778 | AliHLTComponentBlockData bd; | |
779 | FillBlockData(bd); | |
780 | bd.fPtr = outputPtr; | |
781 | // This block's start (offset) is after all other blocks written so far. | |
782 | bd.fOffset = totalSize; | |
783 | bd.fSize = block.BytesUsed(); | |
784 | bd.fDataType = AliHLTMUONConstants::RecHitsBlockDataType(); | |
785 | bd.fSpecification = blocks[n].fSpecification; | |
786 | outputBlocks.push_back(bd); | |
787 | ||
788 | // Increase the total amount of data written so far to our output memory | |
789 | totalSize += block.BytesUsed(); | |
83d66053 | 790 | |
791 | if (fHitRec->GenerateClusterInfo()) | |
792 | { | |
793 | // Create a new output clusters data block and initialise the header. | |
794 | AliHLTMUONClustersBlockWriter clustblock(outputPtr+totalSize, size-totalSize); | |
795 | if (not clustblock.InitCommonHeader()) | |
796 | { | |
797 | HLTError("There is not enough space in the output buffer for the new clusters data block." | |
798 | " We require at least %u bytes, but have %u bytes left.", | |
799 | sizeof(AliHLTMUONClustersBlockWriter::HeaderType), | |
800 | clustblock.BufferSize() | |
801 | ); | |
802 | break; | |
803 | } | |
804 | ||
805 | AliHLTUInt32_t nofClusters = clustblock.MaxNumberOfEntries(); | |
806 | bool filledOk = fHitRec->FillClusterData(clustblock.GetArray(), nofClusters); | |
807 | // nofClusters should now contain the number of clusters filled. | |
808 | assert( nofClusters <= clustblock.MaxNumberOfEntries() ); | |
809 | clustblock.SetNumberOfEntries(nofClusters); | |
810 | ||
811 | // Fill a block data structure for our output block. | |
812 | AliHLTComponentBlockData bdc; | |
813 | FillBlockData(bdc); | |
814 | bdc.fPtr = outputPtr; | |
815 | // This block's start (offset) is after all other blocks written so far. | |
816 | bdc.fOffset = totalSize; | |
817 | bdc.fSize = clustblock.BytesUsed(); | |
818 | bdc.fDataType = AliHLTMUONConstants::ClusterBlockDataType(); | |
819 | bdc.fSpecification = blocks[n].fSpecification; | |
820 | outputBlocks.push_back(bdc); | |
821 | ||
822 | // Increase the total amount of data written so far to our output memory | |
823 | totalSize += clustblock.BytesUsed(); | |
824 | ||
825 | if (not filledOk) | |
826 | { | |
827 | HLTError("We have overflowed the output buffer space for the new clusters data block."); | |
828 | break; | |
829 | } | |
830 | } | |
831 | ||
832 | if (fHitRec->GenerateChannelInfo()) | |
833 | { | |
834 | // Create a new output channels data block and initialise the header. | |
835 | AliHLTMUONChannelsBlockWriter channelblock(outputPtr+totalSize, size-totalSize); | |
836 | if (not channelblock.InitCommonHeader()) | |
837 | { | |
838 | HLTError("There is not enough space in the output buffer for the new channels data block." | |
839 | " We require at least %u bytes, but have %u bytes left.", | |
840 | sizeof(AliHLTMUONChannelsBlockWriter::HeaderType), | |
841 | channelblock.BufferSize() | |
842 | ); | |
843 | break; | |
844 | } | |
845 | ||
846 | AliHLTUInt32_t nofChannels = channelblock.MaxNumberOfEntries(); | |
847 | bool filledOk = fHitRec->FillChannelData(channelblock.GetArray(), nofChannels); | |
848 | // nofChannels should now contain the number of channels filled. | |
849 | assert( nofChannels <= channelblock.MaxNumberOfEntries() ); | |
850 | channelblock.SetNumberOfEntries(nofChannels); | |
851 | ||
852 | // Fill a block data structure for our output block. | |
853 | AliHLTComponentBlockData bdc; | |
854 | FillBlockData(bdc); | |
855 | bdc.fPtr = outputPtr; | |
856 | // This block's start (offset) is after all other blocks written so far. | |
857 | bdc.fOffset = totalSize; | |
858 | bdc.fSize = channelblock.BytesUsed(); | |
859 | bdc.fDataType = AliHLTMUONConstants::ChannelBlockDataType(); | |
860 | bdc.fSpecification = blocks[n].fSpecification; | |
861 | outputBlocks.push_back(bdc); | |
862 | ||
863 | // Increase the total amount of data written so far to our output memory | |
864 | totalSize += channelblock.BytesUsed(); | |
865 | ||
866 | if (not filledOk) | |
867 | { | |
868 | HLTError("We have overflowed the output buffer space for the new channels data block."); | |
869 | break; | |
870 | } | |
871 | } | |
5ff5f960 | 872 | } |
29486e5a | 873 | // Finally we set the total size of output memory we consumed. |
874 | size = totalSize; | |
875 | ||
876 | return 0; | |
b0201cbe | 877 | } |
878 | ||
879 | ||
a6b16447 | 880 | void AliHLTMUONHitReconstructorComponent::FreeMemory() |
881 | { | |
882 | /// Deletes any allocated objects if they are allocated else nothing is | |
883 | /// done for objects not yet allocated. | |
884 | /// This is used as a helper method to make sure the corresponding pointers | |
93a75941 | 885 | /// are NULL and we get back to a well defined state. |
a6b16447 | 886 | |
887 | if (fHitRec != NULL) | |
888 | { | |
889 | delete fHitRec; | |
890 | fHitRec = NULL; | |
891 | } | |
93a75941 | 892 | if (fLut != NULL) |
893 | { | |
878cb83d | 894 | delete [] fLut; |
93a75941 | 895 | fLut = NULL; |
896 | fLutSize = 0; | |
897 | } | |
a6b16447 | 898 | |
899 | fIdToEntry.clear(); | |
83d66053 | 900 | fMaxEntryPerBusPatch.clear(); |
a6b16447 | 901 | } |
902 | ||
903 | ||
93a75941 | 904 | int AliHLTMUONHitReconstructorComponent::ReadLookUpTable(const char* lutFileName) |
ee3678d3 | 905 | { |
93a75941 | 906 | /// Read in the lookup table from a text file. |
907 | /// Note that this method could leave fLut allocated which is cleaned up | |
908 | /// by DoInit with a call to FreeMemory(). | |
909 | ||
910 | assert( fLut == NULL ); | |
911 | assert( fLutSize == 0 ); | |
912 | assert( fIdToEntry.empty() ); | |
83d66053 | 913 | assert( fMaxEntryPerBusPatch.empty() ); |
93a75941 | 914 | |
915 | std::ifstream file(lutFileName); | |
916 | if (not file.good()) | |
917 | { | |
918 | HLTError("Could not open the LUT file %s", lutFileName); | |
919 | return -ENOENT; | |
920 | } | |
921 | ||
922 | // First count the number of lines of text in the LUT file before decoding. | |
923 | // This is not the most optimal. It would be better to read and decode at the | |
924 | // same time but we are not allowed to use STL and ROOT containers are too | |
925 | // heavy for this task. At least this is done only at the start of run. | |
926 | std::string str; | |
927 | AliHLTUInt32_t lineCount = 0; | |
928 | while (std::getline(file, str)) lineCount++; | |
929 | if (not file.eof()) | |
930 | { | |
931 | HLTError("There was a problem reading the LUT file %s", lutFileName); | |
932 | return -EIO; | |
933 | } | |
934 | if (lineCount == 0) | |
935 | { | |
936 | HLTWarning("The LUT file %s was empty.", lutFileName); | |
937 | } | |
938 | ||
939 | // Add one extra LUT line for the first element which is used as a sentinel value. | |
940 | lineCount++; | |
941 | ||
942 | try | |
943 | { | |
944 | fLut = new AliHLTMUONHitRecoLutRow[lineCount]; | |
945 | fLutSize = lineCount; | |
946 | } | |
947 | catch (const std::bad_alloc&) | |
948 | { | |
949 | HLTError("Could not allocate more memory for the lookuptable."); | |
950 | return -ENOMEM; | |
951 | } | |
952 | ||
953 | // Initialise the sentinel value. | |
954 | fLut[0].fDetElemId = 0; | |
955 | fLut[0].fIX = 0; | |
956 | fLut[0].fIY = 0; | |
957 | fLut[0].fRealX = 0.0; | |
958 | fLut[0].fRealY = 0.0; | |
959 | fLut[0].fRealZ = 0.0; | |
960 | fLut[0].fHalfPadSize = 0.0; | |
961 | fLut[0].fPlane = -1; | |
962 | fLut[0].fPed = -1; | |
963 | fLut[0].fSigma = -1; | |
964 | fLut[0].fA0 = -1; | |
965 | fLut[0].fA1 = -1; | |
966 | fLut[0].fThres = -1; | |
967 | fLut[0].fSat = -1; | |
968 | ||
969 | // Clear the eof flag and start reading from the beginning of the file again. | |
970 | file.clear(); | |
971 | file.seekg(0, std::ios::beg); | |
972 | if (not file.good()) | |
973 | { | |
974 | HLTError("There was a problem seeking in the LUT file %s", lutFileName); | |
975 | return -EIO; | |
976 | } | |
977 | ||
83d66053 | 978 | AliHLTInt32_t idManuChannel,buspatchId; |
93a75941 | 979 | for (AliHLTUInt32_t i = 1; i < fLutSize; i++) |
980 | { | |
981 | if (std::getline(file, str).fail()) | |
982 | { | |
983 | HLTError("There was a problem reading line %d of LUT file %s", i, lutFileName); | |
984 | return -EIO; | |
985 | } | |
986 | ||
987 | int result = sscanf( | |
5533735a | 988 | str.c_str(), "%14d\t%14d\t%14d\t%14d\t%23e\t%23e\t%23e\t%23e\t%14d\t%23e\t%23e\t%23e\t%23e\t%14d\t%14d", |
93a75941 | 989 | &idManuChannel, &fLut[i].fDetElemId, &fLut[i].fIX, |
990 | &fLut[i].fIY, &fLut[i].fRealX, | |
991 | &fLut[i].fRealY, &fLut[i].fRealZ, | |
992 | &fLut[i].fHalfPadSize, &fLut[i].fPlane, | |
993 | &fLut[i].fPed, &fLut[i].fSigma, &fLut[i].fA0, | |
994 | &fLut[i].fA1, &fLut[i].fThres, &fLut[i].fSat | |
995 | ); | |
996 | ||
997 | if (result != 15) | |
998 | { | |
999 | HLTError("Line %d in LUT file %s does not contain 15 elements.", i, lutFileName); | |
1000 | return -EIO; | |
1001 | } | |
83d66053 | 1002 | buspatchId = (idManuChannel>>17) & 0x7FF; |
93a75941 | 1003 | fIdToEntry[idManuChannel] = i; |
83d66053 | 1004 | fMaxEntryPerBusPatch[buspatchId] = fMaxEntryPerBusPatch[buspatchId] + 1; |
1005 | ||
1006 | } | |
1007 | ||
1008 | MaxEntryPerBusPatch::iterator it; | |
fd5b812e | 1009 | for(it=fMaxEntryPerBusPatch.begin(); it!=fMaxEntryPerBusPatch.end(); it++){ |
1010 | HLTDebug("fMaxEntryPerBusPatch[%d] : %d",it->first,it->second); | |
1011 | fMaxEntryPerBusPatch[it->first] = AliHLTInt32_t(0.05*(it->second));///< for 10% occupancy | |
1012 | HLTDebug("fMaxEntryPerBusPatch[%d] : %d",it->first,it->second); | |
93a75941 | 1013 | } |
1014 | ||
1015 | return 0; | |
ee3678d3 | 1016 | } |
1017 | ||
1018 | ||
ffc1a6f6 | 1019 | int AliHLTMUONHitReconstructorComponent::ReadLutFromCDB() |
b0201cbe | 1020 | { |
dba14d7d | 1021 | /// Reads LUT from CDB. |
ffc1a6f6 | 1022 | /// To override the default CDB path and / or run number the |
1023 | /// SetCDBPathAndRunNo(cdbPath, run) method should be called before this | |
1024 | /// method. | |
93a75941 | 1025 | |
1026 | assert( fLut == NULL ); | |
1027 | assert( fLutSize == 0 ); | |
1028 | assert( fIdToEntry.empty() ); | |
83d66053 | 1029 | assert( fMaxEntryPerBusPatch.empty() ); |
93a75941 | 1030 | |
a3d4b6ba | 1031 | if (fDDL == -1) |
1032 | { | |
1033 | HLTError("No DDL number specified for which to load LUT data from CDB."); | |
1034 | return -EINVAL; | |
1035 | } | |
1036 | ||
93a75941 | 1037 | std::vector<AliHLTMUONHitRecoLutRow> lutList; |
1038 | AliHLTMUONHitRecoLutRow lut; | |
1039 | AliHLTUInt32_t iEntry = 0; | |
1040 | ||
ffc1a6f6 | 1041 | int result = FetchMappingStores(); |
dba14d7d | 1042 | // Error message already generated in FetchMappingStores. |
1043 | if (result != 0) return result; | |
93a75941 | 1044 | AliMpDDLStore* ddlStore = AliMpDDLStore::Instance(); |
dba14d7d | 1045 | |
93a75941 | 1046 | AliMpSegmentation* mpSegFactory = AliMpSegmentation::Instance(); |
1047 | if (mpSegFactory == NULL) | |
1048 | { | |
1049 | HLTError("Could not find segmentation mapping (AliMpSegmentation) instance."); | |
1050 | return -EIO; | |
1051 | } | |
1052 | ||
61d982d3 | 1053 | // Only load geometry if not already loaded. |
1054 | if (AliGeomManager::GetGeometry() == NULL) | |
1055 | { | |
1056 | AliGeomManager::LoadGeometry(); | |
1057 | } | |
93a75941 | 1058 | AliMUONGeometryTransformer chamberGeometryTransformer; |
1059 | if (not chamberGeometryTransformer.LoadGeometryData()) | |
1060 | { | |
1061 | HLTError("Failed to load geomerty data."); | |
1062 | return -ENOENT; | |
1063 | } | |
fd5b812e | 1064 | |
ffc1a6f6 | 1065 | AliMUONCalibrationData calibData(AliCDBManager::Instance()->GetRun()); |
93a75941 | 1066 | |
56f0ccdf | 1067 | bool skippedPads = false; |
93a75941 | 1068 | Int_t chamberId; |
1069 | ||
75a65a51 | 1070 | for(Int_t iCh = 0; iCh < 10; iCh++) |
93a75941 | 1071 | { |
1072 | chamberId = iCh; | |
1073 | ||
1074 | AliMpDEIterator it; | |
1075 | for ( it.First(chamberId); ! it.IsDone(); it.Next() ) | |
1076 | { | |
1077 | Int_t detElemId = it.CurrentDEId(); | |
1078 | int iDDL = ddlStore->GetDetElement(detElemId)->GetDdlId(); | |
1079 | if (iDDL != fDDL) continue; | |
1080 | ||
1081 | for (Int_t iCath = 0 ; iCath <= 1 ; iCath++) | |
1082 | { | |
1083 | AliMp::CathodType cath; | |
1084 | ||
1085 | if(iCath == 0) | |
1086 | cath = AliMp::kCath0; | |
1087 | else | |
1088 | cath = AliMp::kCath1; | |
1089 | ||
1090 | const AliMpVSegmentation* seg = mpSegFactory->GetMpSegmentation(detElemId, cath); | |
1091 | AliMp::PlaneType plane = seg->PlaneType(); | |
1092 | Int_t maxIX = seg->MaxPadIndexX(); | |
1093 | Int_t maxIY = seg->MaxPadIndexY(); | |
1094 | ||
1095 | Int_t idManuChannel, manuId, channelId, buspatchId; | |
1096 | AliHLTFloat32_t padSizeX, padSizeY; | |
1097 | AliHLTFloat32_t halfPadSize; | |
fd5b812e | 1098 | AliHLTFloat32_t padSizeXY; |
93a75941 | 1099 | Double_t realX, realY, realZ; |
1100 | Double_t localX, localY, localZ; | |
1101 | Float_t calibA0Coeff,calibA1Coeff,pedestal,sigma; | |
56f0ccdf | 1102 | Float_t thresold,saturation; |
93a75941 | 1103 | |
1104 | // Pad Info of a slat to print in lookuptable | |
1105 | for (Int_t iX = 0; iX<= maxIX ; iX++) | |
1106 | for (Int_t iY = 0; iY<= maxIY ; iY++) | |
1107 | { | |
53eb3786 | 1108 | #ifndef HAVE_NOT_MUON_ALIMPPAD_GETPOSITION |
168e9c4d | 1109 | if (not seg->HasPadByIndices(iX,iY)) continue; |
53eb3786 | 1110 | #else // old AliMpPad functionality < r 31742 |
1111 | if (not seg->HasPad(AliMpIntPair(iX,iY))) continue; | |
1112 | #endif | |
93a75941 | 1113 | |
53eb3786 | 1114 | #ifndef HAVE_NOT_MUON_ALIMPPAD_GETPOSITION |
168e9c4d | 1115 | AliMpPad pad = seg->PadByIndices(iX,iY, kFALSE); |
53eb3786 | 1116 | #else // old AliMpPad functionality < r 31742 |
1117 | AliMpPad pad = seg->PadByIndices(AliMpIntPair(iX,iY), kFALSE); | |
1118 | #endif | |
93a75941 | 1119 | |
1120 | // Getting Manu id | |
53eb3786 | 1121 | #ifndef HAVE_NOT_MUON_ALIMPPAD_GETPOSITION |
168e9c4d | 1122 | manuId = pad.GetManuId(); |
53eb3786 | 1123 | #else // old AliMpPad functionality < r 31742 |
1124 | manuId = pad.GetLocation().GetFirst(); | |
1125 | #endif | |
93a75941 | 1126 | manuId &= 0x7FF; // 11 bits |
56f0ccdf | 1127 | if (calibData.Gains(detElemId, manuId) == NULL) continue; |
1128 | if (calibData.Pedestals(detElemId, manuId) == NULL) continue; | |
93a75941 | 1129 | |
1130 | buspatchId = ddlStore->GetBusPatchId(detElemId,manuId); | |
1131 | ||
1132 | // Getting channel id | |
53eb3786 | 1133 | #ifndef HAVE_NOT_MUON_ALIMPPAD_GETPOSITION |
168e9c4d | 1134 | channelId = pad.GetManuChannel(); |
53eb3786 | 1135 | #else // old AliMpPad functionality < r 31742 |
1136 | channelId = pad.GetLocation().GetSecond(); | |
1137 | #endif | |
93a75941 | 1138 | channelId &= 0x3F; // 6 bits |
1139 | ||
1140 | idManuChannel = buspatchId << 11; | |
1141 | idManuChannel = (idManuChannel | manuId) << 6; | |
1142 | idManuChannel |= channelId; | |
1143 | ||
53eb3786 | 1144 | #ifndef HAVE_NOT_MUON_ALIMPPAD_GETPOSITION |
6e97fbb8 | 1145 | localX = pad.GetPositionX(); |
1146 | localY = pad.GetPositionY(); | |
53eb3786 | 1147 | #else // old AliMpPad functionality < r 31769 |
1148 | localX = pad.Position().X(); | |
1149 | localY = pad.Position().Y(); | |
1150 | #endif //HAVE_NOT_MUON_ALIMPPAD_GETPOSITION | |
93a75941 | 1151 | localZ = 0.0; |
1152 | ||
1153 | chamberGeometryTransformer.Local2Global( | |
1154 | detElemId,localX,localY,localZ, | |
1155 | realX,realY,realZ | |
1156 | ); | |
1157 | ||
53eb3786 | 1158 | #ifndef HAVE_NOT_MUON_ALIMPPAD_GETPOSITION |
6e97fbb8 | 1159 | padSizeX = AliHLTFloat32_t( pad.GetDimensionX() ); |
1160 | padSizeY = AliHLTFloat32_t( pad.GetDimensionY() ); | |
53eb3786 | 1161 | #else // old AliMpPad functionality < r 31769 |
1162 | padSizeX = AliHLTFloat32_t( pad.Dimensions().X() ); | |
1163 | padSizeY = AliHLTFloat32_t( pad.Dimensions().Y() ); | |
1164 | #endif //HAVE_NOT_MUON_ALIMPPAD_GETPOSITION | |
93a75941 | 1165 | |
90af8855 | 1166 | if (fUseIdealGain) |
1167 | { | |
1168 | calibA0Coeff = 1.0; | |
1169 | calibA1Coeff = 0.0; | |
1170 | thresold = 0; | |
1171 | saturation = 0; | |
1172 | } | |
1173 | else | |
1174 | { | |
1175 | calibA0Coeff = (calibData.Gains(detElemId, manuId))->ValueAsFloat(channelId, 0); | |
1176 | calibA1Coeff = (calibData.Gains(detElemId, manuId))->ValueAsFloat(channelId, 1); | |
56f0ccdf | 1177 | thresold = (calibData.Gains(detElemId, manuId))->ValueAsFloat(channelId, 2); |
1178 | saturation = (calibData.Gains(detElemId, manuId))->ValueAsFloat(channelId, 4); | |
90af8855 | 1179 | } |
93a75941 | 1180 | |
1181 | pedestal = (calibData.Pedestals(detElemId, manuId))->ValueAsFloat(channelId, 0); | |
1182 | sigma = (calibData.Pedestals(detElemId, manuId))->ValueAsFloat(channelId, 1); | |
1183 | ||
e5ff2d6f | 1184 | // Check if any of the values fetched from the calibration data are |
1185 | // invalid. If they are then skip this pad. | |
1186 | if (calibA0Coeff == AliMUONVCalibParam::InvalidFloatValue() or | |
1187 | calibA1Coeff == AliMUONVCalibParam::InvalidFloatValue() or | |
1188 | thresold == AliMUONVCalibParam::InvalidFloatValue() or | |
1189 | saturation == AliMUONVCalibParam::InvalidFloatValue() or | |
1190 | pedestal == AliMUONVCalibParam::InvalidFloatValue() or | |
1191 | sigma == AliMUONVCalibParam::InvalidFloatValue() | |
1192 | ) | |
1193 | { | |
56f0ccdf | 1194 | if (fWarnIfPadSkipped) |
1195 | { | |
1196 | HLTWarning("Skipping pad on detection element %d, MANU %d, channel %d, since" | |
1197 | " the calibration data contains invalid values in that channel.", | |
1198 | detElemId, manuId, channelId | |
1199 | ); | |
1200 | } | |
1201 | skippedPads = true; | |
e5ff2d6f | 1202 | continue; |
1203 | } | |
1204 | ||
fd5b812e | 1205 | |
1206 | if (plane == 0){ | |
93a75941 | 1207 | halfPadSize = padSizeX; |
fd5b812e | 1208 | padSizeXY = padSizeY; |
1209 | }else{ | |
93a75941 | 1210 | halfPadSize = padSizeY; |
fd5b812e | 1211 | padSizeXY = padSizeX; |
1212 | } | |
1213 | ||
93a75941 | 1214 | fIdToEntry[idManuChannel] = iEntry+1; |
83d66053 | 1215 | fMaxEntryPerBusPatch[buspatchId] = fMaxEntryPerBusPatch[buspatchId] + 1; |
1216 | ||
93a75941 | 1217 | lut.fDetElemId = detElemId; |
1218 | lut.fIX = iX; | |
1219 | lut.fIY = iY; | |
1220 | lut.fRealX = realX; | |
1221 | lut.fRealY = realY; | |
1222 | lut.fRealZ = realZ; | |
1223 | lut.fHalfPadSize = halfPadSize; | |
fd5b812e | 1224 | lut.fPadSizeXY = padSizeXY; |
93a75941 | 1225 | lut.fPlane = plane; |
1226 | lut.fPed = pedestal; | |
1227 | lut.fSigma = sigma; | |
1228 | lut.fA0 = calibA0Coeff; | |
1229 | lut.fA1 = calibA1Coeff; | |
56f0ccdf | 1230 | lut.fThres = Int_t(thresold); |
1231 | lut.fSat = Int_t(saturation); | |
93a75941 | 1232 | |
90af8855 | 1233 | HLTDebug("lut : detele : %d, id : %d, manu : %d, channel : %d, iX : %d, iY: %d, (X,Y) : (%f, %f), padsize : %f, plane : %d, ped : %f, sigma : %f", |
1234 | lut.fDetElemId,idManuChannel,manuId,channelId,lut.fIX,lut.fIY,lut.fRealX,lut.fRealY,lut.fHalfPadSize,lut.fPlane,lut.fPed,lut.fSigma | |
1235 | ); | |
1236 | ||
93a75941 | 1237 | lutList.push_back(lut); |
1238 | iEntry++; | |
1239 | } // iX, iY loop | |
1240 | } // iCath loop | |
1241 | } // detElemId loop | |
1242 | } // ichamber loop | |
56f0ccdf | 1243 | |
1244 | if (skippedPads and not fWarnIfPadSkipped) | |
1245 | { | |
1246 | HLTWarning("Skipped pads since they contained invalid calibration values." | |
1247 | " Use the -warnifpadskipped argument to generate detailed information" | |
1248 | " about which pads were skipped." | |
1249 | ); | |
1250 | } | |
93a75941 | 1251 | |
1252 | try | |
1253 | { | |
1254 | // Use iEntry+1 since we add one extra LUT line for the first element | |
1255 | // which is used as a sentinel value. | |
1256 | fLut = new AliHLTMUONHitRecoLutRow[iEntry+1]; | |
1257 | fLutSize = iEntry+1; | |
90af8855 | 1258 | HLTDebug("Address of new LUT buffer at fLut = %p", fLut); |
93a75941 | 1259 | } |
1260 | catch (const std::bad_alloc&) | |
1261 | { | |
1262 | HLTError("Could not allocate more memory for the lookuptable."); | |
90af8855 | 1263 | //lutList.clear(); not necessary, implicitly done during stack cleanup. |
93a75941 | 1264 | return -ENOMEM; |
1265 | } | |
1266 | ||
1267 | // Initialise the sentinel value. | |
1268 | fLut[0].fDetElemId = 0; | |
1269 | fLut[0].fIX = 0; | |
1270 | fLut[0].fIY = 0; | |
1271 | fLut[0].fRealX = 0.0; | |
1272 | fLut[0].fRealY = 0.0; | |
1273 | fLut[0].fRealZ = 0.0; | |
1274 | fLut[0].fHalfPadSize = 0.0; | |
fd5b812e | 1275 | fLut[0].fPadSizeXY = 0.0; |
93a75941 | 1276 | fLut[0].fPlane = -1; |
1277 | fLut[0].fPed = -1; | |
1278 | fLut[0].fSigma = -1; | |
1279 | fLut[0].fA0 = -1; | |
1280 | fLut[0].fA1 = -1; | |
1281 | fLut[0].fThres = -1; | |
1282 | fLut[0].fSat = -1; | |
1283 | ||
1284 | for (AliHLTUInt32_t i = 0; i < iEntry; i++) | |
1285 | fLut[i+1] = lutList[i]; | |
83d66053 | 1286 | lutList.clear(); |
1287 | ||
1288 | MaxEntryPerBusPatch::iterator it; | |
fd5b812e | 1289 | for(it=fMaxEntryPerBusPatch.begin(); it!=fMaxEntryPerBusPatch.end(); it++){ |
1290 | HLTDebug("fMaxEntryPerBusPatch[%d] : %d",it->first,it->second); | |
1291 | fMaxEntryPerBusPatch[it->first] = AliHLTInt32_t(0.05*(it->second));///< for 10% occupancy | |
1292 | HLTDebug("fMaxEntryPerBusPatch[%d] : %d",it->first,it->second); | |
83d66053 | 1293 | } |
1294 | ||
93a75941 | 1295 | return 0; |
b0201cbe | 1296 | } |
1297 | ||
b0201cbe | 1298 | |
2b7af22a | 1299 | int AliHLTMUONHitReconstructorComponent::ReadDCCutFromCDB() |
ffc1a6f6 | 1300 | { |
1301 | /// Reads the DC cut parameter from the CDB. | |
1302 | ||
1303 | const char* pathToEntry = AliHLTMUONConstants::HitReconstructorCDBPath(); | |
ffc1a6f6 | 1304 | |
1305 | TMap* map = NULL; | |
1306 | int result = FetchTMapFromCDB(pathToEntry, map); | |
1307 | if (result != 0) return result; | |
1308 | ||
1309 | Int_t value = 0; | |
1310 | result = GetPositiveIntFromTMap(map, "dccut", value, pathToEntry, "DC cut"); | |
1311 | if (result != 0) return result; | |
1312 | ||
1313 | assert(fHitRec != NULL); | |
1314 | fHitRec->SetDCCut(value); | |
1315 | ||
2b7af22a | 1316 | HLTDebug("Using DC cut parameter of %d ADC channels.", fHitRec->GetDCCut()); |
1317 | ||
ffc1a6f6 | 1318 | return 0; |
1319 | } | |
1320 | ||
1321 | ||
93a75941 | 1322 | bool AliHLTMUONHitReconstructorComponent::GenerateLookupTable( |
1323 | AliHLTInt32_t ddl, const char* filename, | |
ee3678d3 | 1324 | const char* cdbPath, Int_t run |
1325 | ) | |
b0201cbe | 1326 | { |
93a75941 | 1327 | /// Generates a ASCII text file containing the lookup table (LUT) from |
1328 | /// the CDB, which can be used for the hit reconstructor component later. | |
1329 | /// @param ddl Must be the DDL for which to generate the DDL, | |
f064ef44 | 1330 | /// in the range [0..19]. |
93a75941 | 1331 | /// @param filename The name of the LUT file to generate. |
1332 | /// @param cdbPath The CDB path to use. | |
1333 | /// @param run The run number to use for the CDB. | |
1334 | /// @return True if the generation of the LUT file succeeded. | |
1335 | ||
1336 | AliHLTMUONHitReconstructorComponent comp; | |
1337 | ||
f064ef44 | 1338 | if (ddl < 0 or 19 < ddl) |
93a75941 | 1339 | { |
f064ef44 | 1340 | std::cerr << "ERROR: the DDL number must be in the range [0..19]." << std::endl; |
93a75941 | 1341 | return false; |
1342 | } | |
1343 | ||
1344 | comp.fDDL = ddl; | |
ffc1a6f6 | 1345 | if (comp.SetCDBPathAndRunNo(cdbPath, run) != 0) return false; |
1346 | if (comp.ReadLutFromCDB() != 0) return false; | |
93a75941 | 1347 | |
1348 | char str[1024*4]; | |
1349 | std::fstream file(filename, std::ios::out); | |
1350 | if (not file) | |
1351 | { | |
1352 | std::cerr << "ERROR: could not open file: " << filename << std::endl; | |
1353 | return false; | |
1354 | } | |
1355 | ||
1356 | assert( comp.fLut != NULL ); | |
1357 | ||
1358 | for (IdManuChannelToEntry::iterator id = comp.fIdToEntry.begin(); | |
1359 | id != comp.fIdToEntry.end(); | |
1360 | id++ | |
1361 | ) | |
1362 | { | |
1363 | AliHLTInt32_t idManuChannel = id->first; | |
1364 | AliHLTInt32_t row = id->second; | |
ee3678d3 | 1365 | |
ffc1a6f6 | 1366 | assert( AliHLTUInt32_t(row) < comp.fLutSize ); |
ee3678d3 | 1367 | |
93a75941 | 1368 | sprintf(str, "%d\t%d\t%d\t%d\t%.15e\t%.15e\t%.15e\t%.15e\t%d\t%.15e\t%.15e\t%.15e\t%.15e\t%d\t%d", |
1369 | idManuChannel, comp.fLut[row].fDetElemId, comp.fLut[row].fIX, | |
1370 | comp.fLut[row].fIY, comp.fLut[row].fRealX, | |
1371 | comp.fLut[row].fRealY, comp.fLut[row].fRealZ, | |
1372 | comp.fLut[row].fHalfPadSize, comp.fLut[row].fPlane, | |
1373 | comp.fLut[row].fPed, comp.fLut[row].fSigma, comp.fLut[row].fA0, | |
1374 | comp.fLut[row].fA1, comp.fLut[row].fThres, comp.fLut[row].fSat | |
1375 | ); | |
ee3678d3 | 1376 | |
93a75941 | 1377 | file << str << endl; |
1378 | if (file.fail()) | |
1379 | { | |
1380 | std::cerr << "ERROR: There was an I/O error when writing to the file: " | |
1381 | << filename << std::endl; | |
1382 | return false; | |
1383 | } | |
1384 | } | |
1385 | ||
1386 | return true; | |
b0201cbe | 1387 | } |