b0201cbe |
1 | /************************************************************************** |
960d54ad |
2 | * This file is property of and copyright by the ALICE HLT Project * |
3 | * All rights reserved. * |
b0201cbe |
4 | * * |
960d54ad |
5 | * Primary Authors: * |
6 | * Indranil Das <indra.das@saha.ac.in> * |
b0201cbe |
7 | * * |
8 | * Permission to use, copy, modify and distribute this software and its * |
9 | * documentation strictly for non-commercial purposes is hereby granted * |
10 | * without fee, provided that the above copyright notice appears in all * |
11 | * copies and that both the copyright notice and this permission notice * |
12 | * appear in the supporting documentation. The authors make no claims * |
960d54ad |
13 | * about the suitability of this software for any purpose. It is * |
b0201cbe |
14 | * provided "as is" without express or implied warranty. * |
15 | **************************************************************************/ |
16 | |
17 | /* $Id$ */ |
18 | |
6253e09b |
19 | /// |
20 | /// |
21 | /// The HitRec Component is designed to deal the rawdata inputfiles to findout the |
22 | /// the reconstructed hits. The output is send to the output block for further |
23 | /// processing. |
24 | /// |
25 | /// Author : Indranil Das ( indra.das@saha.ac.in || indra.ehep@gmail.com ) |
26 | /// |
b0201cbe |
27 | |
960d54ad |
28 | #include "AliHLTMUONRecHitsBlockStruct.h" |
b0201cbe |
29 | #include "AliHLTMUONHitReconstructorComponent.h" |
b12fe461 |
30 | #include "AliHLTMUONHitReconstructor.h" |
960d54ad |
31 | #include "AliHLTMUONConstants.h" |
668eee9f |
32 | #include "AliHLTMUONUtils.h" |
5ff5f960 |
33 | #include "AliHLTMUONDataBlockWriter.h" |
a6b16447 |
34 | #include "AliHLTMUONHitReconstructor.h" |
b0201cbe |
35 | #include "AliHLTLogging.h" |
36 | #include "AliHLTSystem.h" |
37 | #include "AliHLTDefinitions.h" |
29486e5a |
38 | #include <cstdlib> |
39 | #include <cerrno> |
40 | #include <cassert> |
93a75941 |
41 | #include <fstream> |
b0201cbe |
42 | |
ee3678d3 |
43 | //STEER |
44 | #include "AliCDBManager.h" |
93a75941 |
45 | #include "AliCDBStorage.h" |
ee3678d3 |
46 | #include "AliGeomManager.h" |
47 | |
48 | //MUON |
49 | #include "AliMUONGeometryTransformer.h" |
50 | #include "AliMUONCalibrationData.h" |
51 | #include "AliMUONVCalibParam.h" |
52 | |
a6b16447 |
53 | //MUON/mapping |
ee3678d3 |
54 | #include "AliMpCDB.h" |
55 | #include "AliMpPad.h" |
56 | #include "AliMpSegmentation.h" |
57 | #include "AliMpDDLStore.h" |
58 | #include "AliMpDEIterator.h" |
59 | #include "AliMpVSegmentation.h" |
60 | #include "AliMpDEManager.h" |
61 | #include "AliMpDetElement.h" |
62 | |
b0201cbe |
63 | ClassImp(AliHLTMUONHitReconstructorComponent) |
64 | |
65 | |
29486e5a |
66 | AliHLTMUONHitReconstructorComponent::AliHLTMUONHitReconstructorComponent() : |
6253e09b |
67 | AliHLTProcessor(), |
29486e5a |
68 | fHitRec(NULL), |
a6b16447 |
69 | fDDL(-1), |
93a75941 |
70 | fLutSize(0), |
71 | fLut(NULL), |
ee3678d3 |
72 | fIdToEntry(), |
29486e5a |
73 | fWarnForUnexpecedBlock(false) |
b0201cbe |
74 | { |
6253e09b |
75 | /// |
76 | /// Default constructor. |
77 | /// |
b0201cbe |
78 | } |
79 | |
960d54ad |
80 | |
b0201cbe |
81 | AliHLTMUONHitReconstructorComponent::~AliHLTMUONHitReconstructorComponent() |
82 | { |
6253e09b |
83 | /// |
84 | /// Default destructor. |
85 | /// |
ee3678d3 |
86 | |
87 | if (fHitRec != NULL) |
88 | { |
89 | delete fHitRec; |
90 | } |
93a75941 |
91 | if (fLut != NULL) |
92 | { |
93 | delete fLut; |
94 | } |
960d54ad |
95 | } |
b0201cbe |
96 | |
960d54ad |
97 | const char* AliHLTMUONHitReconstructorComponent::GetComponentID() |
98 | { |
6253e09b |
99 | /// |
100 | /// Inherited from AliHLTComponent. Returns the component ID. |
101 | /// |
102 | |
29486e5a |
103 | return AliHLTMUONConstants::HitReconstructorId(); |
b0201cbe |
104 | } |
105 | |
b0201cbe |
106 | |
960d54ad |
107 | void AliHLTMUONHitReconstructorComponent::GetInputDataTypes( std::vector<AliHLTComponentDataType>& list) |
108 | { |
6253e09b |
109 | /// |
110 | /// Inherited from AliHLTProcessor. Returns the list of expected input data types. |
111 | /// |
112 | |
29486e5a |
113 | list.clear(); |
668eee9f |
114 | list.push_back( AliHLTMUONConstants::DDLRawDataType() ); |
960d54ad |
115 | } |
b0201cbe |
116 | |
b0201cbe |
117 | |
960d54ad |
118 | AliHLTComponentDataType AliHLTMUONHitReconstructorComponent::GetOutputDataType() |
119 | { |
6253e09b |
120 | /// |
121 | /// Inherited from AliHLTComponent. Returns the output data type. |
122 | /// |
123 | |
29486e5a |
124 | return AliHLTMUONConstants::RecHitsBlockDataType(); |
960d54ad |
125 | } |
b0201cbe |
126 | |
b0201cbe |
127 | |
960d54ad |
128 | void AliHLTMUONHitReconstructorComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier ) |
129 | { |
6253e09b |
130 | /// |
131 | /// Inherited from AliHLTComponent. Returns an estimate of the expected output data size. |
132 | /// |
133 | |
13f09bc1 |
134 | constBase = sizeof(AliHLTMUONRecHitsBlockWriter::HeaderType); |
29486e5a |
135 | inputMultiplier = 1; |
960d54ad |
136 | } |
b0201cbe |
137 | |
b0201cbe |
138 | |
960d54ad |
139 | AliHLTComponent* AliHLTMUONHitReconstructorComponent::Spawn() |
140 | { |
6253e09b |
141 | /// |
142 | /// Inherited from AliHLTComponent. Creates a new object instance. |
143 | /// |
144 | |
29486e5a |
145 | return new AliHLTMUONHitReconstructorComponent; |
960d54ad |
146 | } |
b0201cbe |
147 | |
b0201cbe |
148 | |
29486e5a |
149 | int AliHLTMUONHitReconstructorComponent::DoInit(int argc, const char** argv) |
960d54ad |
150 | { |
6253e09b |
151 | /// |
152 | /// Inherited from AliHLTComponent. |
153 | /// Parses the command line parameters and initialises the component. |
154 | /// |
b0201cbe |
155 | |
ee3678d3 |
156 | HLTInfo("Initialising dHLT hit reconstruction component."); |
960d54ad |
157 | |
93a75941 |
158 | // Must make sure that fHitRec and fLut is deleted if it is still |
159 | // allocated for whatever reason. |
a6b16447 |
160 | FreeMemory(); |
161 | |
ee3678d3 |
162 | try |
163 | { |
164 | fHitRec = new AliHLTMUONHitReconstructor(); |
960d54ad |
165 | } |
ee3678d3 |
166 | catch (const std::bad_alloc&) |
b8d467da |
167 | { |
ee3678d3 |
168 | HLTError("Could not allocate more memory for the hit reconstructor component."); |
169 | return -ENOMEM; |
b8d467da |
170 | } |
960d54ad |
171 | |
a6b16447 |
172 | // Initialise fields with default values then parse the command line. |
173 | fDDL = -1; |
174 | fIdToEntry.clear(); |
ee3678d3 |
175 | fWarnForUnexpecedBlock = false; |
a6b16447 |
176 | |
ee3678d3 |
177 | const char* lutFileName = NULL; |
178 | const char* cdbPath = NULL; |
179 | Int_t run = -1; |
180 | bool useCDB = false; |
181 | |
182 | for (int i = 0; i < argc; i++) |
183 | { |
184 | HLTDebug("argv[%d] == %s", i, argv[i]); |
185 | |
186 | if (strcmp( argv[i], "-ddl" ) == 0) |
187 | { |
188 | if (argc <= i+1) |
189 | { |
190 | HLTError("The DDL number was not specified. Must be in the range [13..20]."); |
a6b16447 |
191 | FreeMemory(); // Make sure we cleanup to avoid partial initialisation. |
192 | return -EINVAL; |
ee3678d3 |
193 | } |
194 | |
195 | char* cpErr = NULL; |
196 | unsigned long num = strtoul( argv[i+1], &cpErr, 0 ); |
197 | if (cpErr == NULL or *cpErr != '\0') |
198 | { |
93a75941 |
199 | HLTError("Cannot convert '%s' to DDL a number.", argv[i+1] ); |
a6b16447 |
200 | FreeMemory(); // Make sure we cleanup to avoid partial initialisation. |
201 | return -EINVAL; |
ee3678d3 |
202 | } |
203 | if (num < 13 or 20 < num) |
204 | { |
205 | HLTError("The DDL number must be in the range [13..20]."); |
a6b16447 |
206 | FreeMemory(); // Make sure we cleanup to avoid partial initialisation. |
207 | return -EINVAL; |
ee3678d3 |
208 | } |
93a75941 |
209 | fDDL = num - 1; // convert to range [12..19] |
ee3678d3 |
210 | |
211 | i++; |
212 | continue; |
213 | } // -ddl argument |
214 | |
215 | if (strcmp( argv[i], "-lut" ) == 0) |
216 | { |
217 | if (argc <= i+1) |
218 | { |
219 | HLTError("The lookup table filename was not specified."); |
a6b16447 |
220 | FreeMemory(); // Make sure we cleanup to avoid partial initialisation. |
221 | return -EINVAL; |
ee3678d3 |
222 | } |
223 | lutFileName = argv[i+1]; |
224 | i++; |
225 | continue; |
226 | } // -lut argument |
227 | |
228 | if (strcmp( argv[i], "-cdb" ) == 0) |
229 | { |
230 | useCDB = true; |
231 | continue; |
232 | } // -cdb argument |
233 | |
234 | if (strcmp( argv[i], "-cdbpath" ) == 0) |
235 | { |
236 | if ( argc <= i+1 ) |
237 | { |
238 | HLTError("The CDB path was not specified." ); |
a6b16447 |
239 | FreeMemory(); // Make sure we cleanup to avoid partial initialisation. |
240 | return -EINVAL; |
ee3678d3 |
241 | } |
242 | cdbPath = argv[i+1]; |
243 | useCDB = true; |
244 | i++; |
245 | continue; |
246 | } // -cdb argument |
247 | |
248 | if (strcmp( argv[i], "-run" ) == 0) |
249 | { |
250 | if ( argc <= i+1 ) |
251 | { |
252 | HLTError("The RUN number was not specified." ); |
a6b16447 |
253 | FreeMemory(); // Make sure we cleanup to avoid partial initialisation. |
254 | return -EINVAL; |
ee3678d3 |
255 | } |
256 | |
257 | char* cpErr = NULL; |
258 | run = Int_t( strtoul(argv[i+1], &cpErr, 0) ); |
259 | if (cpErr == NULL or *cpErr != '\0') |
260 | { |
261 | HLTError("Cannot convert '%s' to a valid run number." |
262 | " Expected an integer value.", argv[i+1] |
263 | ); |
a6b16447 |
264 | FreeMemory(); // Make sure we cleanup to avoid partial initialisation. |
265 | return -EINVAL; |
ee3678d3 |
266 | } |
267 | |
268 | i++; |
269 | continue; |
270 | } // -run argument |
271 | |
272 | if (strcmp( argv[i], "-warn_on_unexpected_block" ) == 0) |
273 | { |
274 | fWarnForUnexpecedBlock = true; |
275 | continue; |
276 | } |
277 | |
278 | HLTError("Unknown option '%s'", argv[i]); |
a6b16447 |
279 | FreeMemory(); // Make sure we cleanup to avoid partial initialisation. |
280 | return -EINVAL; |
ee3678d3 |
281 | |
282 | } // for loop |
283 | |
93a75941 |
284 | if (lutFileName == NULL) useCDB = true; |
285 | |
a6b16447 |
286 | if (fDDL == -1) |
287 | { |
288 | HLTWarning("DDL number not specified. Cannot check if incomming data is valid."); |
289 | } |
290 | |
93a75941 |
291 | int result = 0; |
ee3678d3 |
292 | if (useCDB) |
293 | { |
93a75941 |
294 | HLTInfo("Loading lookup table information from CDB for DDL %d.", fDDL+1); |
295 | if (fDDL == -1) |
296 | HLTWarning("DDL number not specified. The lookup table loaded from CDB will be empty!"); |
297 | result = ReadCDB(cdbPath, run); |
960d54ad |
298 | } |
ee3678d3 |
299 | else |
300 | { |
93a75941 |
301 | HLTInfo("Loading lookup table information from file %s.", lutFileName); |
302 | result = ReadLookUpTable(lutFileName); |
ee3678d3 |
303 | } |
93a75941 |
304 | if (result != 0) |
ee3678d3 |
305 | { |
93a75941 |
306 | // Error messages already generated in ReadCDB or ReadLookUpTable. |
a6b16447 |
307 | FreeMemory(); // Make sure we cleanup to avoid partial initialisation. |
93a75941 |
308 | return result; |
ee3678d3 |
309 | } |
310 | |
93a75941 |
311 | fHitRec->SetLookUpTable(fLut, &fIdToEntry); |
ee3678d3 |
312 | |
313 | return 0; |
b0201cbe |
314 | } |
315 | |
960d54ad |
316 | |
317 | int AliHLTMUONHitReconstructorComponent::DoDeinit() |
318 | { |
6253e09b |
319 | /// |
320 | /// Inherited from AliHLTComponent. Performs a cleanup of the component. |
321 | /// |
322 | |
ee3678d3 |
323 | HLTInfo("Deinitialising dHLT hit reconstruction component."); |
a6b16447 |
324 | FreeMemory(); |
ee3678d3 |
325 | return 0; |
b0201cbe |
326 | } |
327 | |
b0201cbe |
328 | |
960d54ad |
329 | int AliHLTMUONHitReconstructorComponent::DoEvent( |
330 | const AliHLTComponentEventData& evtData, |
b8d467da |
331 | const AliHLTComponentBlockData* blocks, |
332 | AliHLTComponentTriggerData& /*trigData*/, |
333 | AliHLTUInt8_t* outputPtr, |
960d54ad |
334 | AliHLTUInt32_t& size, |
335 | std::vector<AliHLTComponentBlockData>& outputBlocks |
336 | ) |
337 | { |
6253e09b |
338 | /// |
339 | /// Inherited from AliHLTProcessor. Processes the new event data. |
340 | /// |
341 | |
29486e5a |
342 | // Process an event |
343 | unsigned long totalSize = 0; // Amount of memory currently consumed in bytes. |
b0201cbe |
344 | |
29486e5a |
345 | HLTDebug("Processing event %llu with %u input data blocks.", |
346 | evtData.fEventID, evtData.fBlockCnt |
347 | ); |
348 | |
349 | // Loop over all input blocks in the event |
450e0b36 |
350 | for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++) |
5ff5f960 |
351 | { |
450e0b36 |
352 | HLTDebug("Handling block: %u, with fDataType = '%s', fPtr = %p and fSize = %u bytes.", |
353 | n, DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fPtr, blocks[n].fSize |
5ff5f960 |
354 | ); |
29486e5a |
355 | |
668eee9f |
356 | if (blocks[n].fDataType != AliHLTMUONConstants::DDLRawDataType() |
357 | or not AliHLTMUONUtils::IsTrackerDDL(blocks[n].fSpecification) |
358 | ) |
29486e5a |
359 | { |
360 | // Log a message indicating that we got a data block that we |
361 | // do not know how to handle. |
29486e5a |
362 | if (fWarnForUnexpecedBlock) |
450e0b36 |
363 | HLTWarning("Received a data block of a type we cannot handle: '%s', spec: 0x%X", |
364 | DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification |
29486e5a |
365 | ); |
366 | else |
450e0b36 |
367 | HLTDebug("Received a data block of a type we cannot handle: '%s', spec: 0x%X", |
368 | DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification |
29486e5a |
369 | ); |
370 | |
371 | continue; |
372 | } |
373 | |
a6b16447 |
374 | if (fDDL != -1) |
ee3678d3 |
375 | { |
a6b16447 |
376 | bool ddl[22]; |
377 | AliHLTMUONUtils::UnpackSpecBits(blocks[n].fSpecification, ddl); |
378 | if (not ddl[fDDL]) |
379 | { |
380 | HLTWarning("Received raw data from an unexpected DDL."); |
381 | } |
ee3678d3 |
382 | } |
383 | |
29486e5a |
384 | // Create a new output data block and initialise the header. |
385 | AliHLTMUONRecHitsBlockWriter block(outputPtr+totalSize, size-totalSize); |
386 | if (not block.InitCommonHeader()) |
387 | { |
8bade2be |
388 | HLTError("There is not enough space in the output buffer for the new data block." |
29486e5a |
389 | " We require at least %u bytes, but have %u bytes left.", |
390 | sizeof(AliHLTMUONRecHitsBlockWriter::HeaderType), |
391 | block.BufferSize() |
392 | ); |
393 | break; |
394 | } |
395 | |
396 | AliHLTUInt32_t totalDDLSize = blocks[n].fSize / sizeof(AliHLTUInt32_t); |
397 | AliHLTUInt32_t ddlRawDataSize = totalDDLSize - fHitRec->GetkDDLHeaderSize(); |
398 | AliHLTUInt32_t* buffer = reinterpret_cast<AliHLTUInt32_t*>(blocks[n].fPtr) |
399 | + fHitRec->GetkDDLHeaderSize(); |
400 | AliHLTUInt32_t nofHit = block.MaxNumberOfEntries(); |
401 | |
ee3678d3 |
402 | #ifdef DEBUG |
29486e5a |
403 | HLTDebug("=========== Dumping DDL payload buffer =========="); |
404 | for (AliHLTUInt32_t j = 0; j < totalDDLSize; j++) |
405 | HLTDebug("buffer[%d] : %x",j,buffer[j]); |
406 | HLTDebug("================== End of dump ================="); |
ee3678d3 |
407 | #endif // DEBUG |
29486e5a |
408 | |
409 | if (not fHitRec->Run(buffer, ddlRawDataSize, block.GetArray(), nofHit)) |
410 | { |
411 | HLTError("Error while processing of hit reconstruction algorithm."); |
412 | size = totalSize; // Must tell the framework how much buffer space was used. |
a6b16447 |
413 | return -EIO; |
29486e5a |
414 | } |
415 | |
416 | // nofHit should now contain the number of reconstructed hits actually found |
417 | // and filled into the output data block, so we can set this number. |
418 | assert( nofHit <= block.MaxNumberOfEntries() ); |
419 | block.SetNumberOfEntries(nofHit); |
420 | |
421 | HLTDebug("Number of reconstructed hits found is %d", nofHit); |
422 | |
423 | // Fill a block data structure for our output block. |
424 | AliHLTComponentBlockData bd; |
425 | FillBlockData(bd); |
426 | bd.fPtr = outputPtr; |
427 | // This block's start (offset) is after all other blocks written so far. |
428 | bd.fOffset = totalSize; |
429 | bd.fSize = block.BytesUsed(); |
430 | bd.fDataType = AliHLTMUONConstants::RecHitsBlockDataType(); |
431 | bd.fSpecification = blocks[n].fSpecification; |
432 | outputBlocks.push_back(bd); |
433 | |
434 | // Increase the total amount of data written so far to our output memory |
435 | totalSize += block.BytesUsed(); |
5ff5f960 |
436 | } |
29486e5a |
437 | // Finally we set the total size of output memory we consumed. |
438 | size = totalSize; |
439 | |
440 | return 0; |
b0201cbe |
441 | } |
442 | |
443 | |
a6b16447 |
444 | void AliHLTMUONHitReconstructorComponent::FreeMemory() |
445 | { |
446 | /// Deletes any allocated objects if they are allocated else nothing is |
447 | /// done for objects not yet allocated. |
448 | /// This is used as a helper method to make sure the corresponding pointers |
93a75941 |
449 | /// are NULL and we get back to a well defined state. |
a6b16447 |
450 | |
451 | if (fHitRec != NULL) |
452 | { |
453 | delete fHitRec; |
454 | fHitRec = NULL; |
455 | } |
93a75941 |
456 | if (fLut != NULL) |
457 | { |
458 | delete fLut; |
459 | fLut = NULL; |
460 | fLutSize = 0; |
461 | } |
a6b16447 |
462 | |
463 | fIdToEntry.clear(); |
464 | } |
465 | |
466 | |
93a75941 |
467 | int AliHLTMUONHitReconstructorComponent::ReadLookUpTable(const char* lutFileName) |
ee3678d3 |
468 | { |
93a75941 |
469 | /// Read in the lookup table from a text file. |
470 | /// Note that this method could leave fLut allocated which is cleaned up |
471 | /// by DoInit with a call to FreeMemory(). |
472 | |
473 | assert( fLut == NULL ); |
474 | assert( fLutSize == 0 ); |
475 | assert( fIdToEntry.empty() ); |
476 | |
477 | std::ifstream file(lutFileName); |
478 | if (not file.good()) |
479 | { |
480 | HLTError("Could not open the LUT file %s", lutFileName); |
481 | return -ENOENT; |
482 | } |
483 | |
484 | // First count the number of lines of text in the LUT file before decoding. |
485 | // This is not the most optimal. It would be better to read and decode at the |
486 | // same time but we are not allowed to use STL and ROOT containers are too |
487 | // heavy for this task. At least this is done only at the start of run. |
488 | std::string str; |
489 | AliHLTUInt32_t lineCount = 0; |
490 | while (std::getline(file, str)) lineCount++; |
491 | if (not file.eof()) |
492 | { |
493 | HLTError("There was a problem reading the LUT file %s", lutFileName); |
494 | return -EIO; |
495 | } |
496 | if (lineCount == 0) |
497 | { |
498 | HLTWarning("The LUT file %s was empty.", lutFileName); |
499 | } |
500 | |
501 | // Add one extra LUT line for the first element which is used as a sentinel value. |
502 | lineCount++; |
503 | |
504 | try |
505 | { |
506 | fLut = new AliHLTMUONHitRecoLutRow[lineCount]; |
507 | fLutSize = lineCount; |
508 | } |
509 | catch (const std::bad_alloc&) |
510 | { |
511 | HLTError("Could not allocate more memory for the lookuptable."); |
512 | return -ENOMEM; |
513 | } |
514 | |
515 | // Initialise the sentinel value. |
516 | fLut[0].fDetElemId = 0; |
517 | fLut[0].fIX = 0; |
518 | fLut[0].fIY = 0; |
519 | fLut[0].fRealX = 0.0; |
520 | fLut[0].fRealY = 0.0; |
521 | fLut[0].fRealZ = 0.0; |
522 | fLut[0].fHalfPadSize = 0.0; |
523 | fLut[0].fPlane = -1; |
524 | fLut[0].fPed = -1; |
525 | fLut[0].fSigma = -1; |
526 | fLut[0].fA0 = -1; |
527 | fLut[0].fA1 = -1; |
528 | fLut[0].fThres = -1; |
529 | fLut[0].fSat = -1; |
530 | |
531 | // Clear the eof flag and start reading from the beginning of the file again. |
532 | file.clear(); |
533 | file.seekg(0, std::ios::beg); |
534 | if (not file.good()) |
535 | { |
536 | HLTError("There was a problem seeking in the LUT file %s", lutFileName); |
537 | return -EIO; |
538 | } |
539 | |
540 | AliHLTInt32_t idManuChannel; |
541 | for (AliHLTUInt32_t i = 1; i < fLutSize; i++) |
542 | { |
543 | if (std::getline(file, str).fail()) |
544 | { |
545 | HLTError("There was a problem reading line %d of LUT file %s", i, lutFileName); |
546 | return -EIO; |
547 | } |
548 | |
549 | int result = sscanf( |
550 | str.c_str(), "%d\t%d\t%d\t%d\t%e\t%e\t%e\t%e\t%d\t%e\t%e\t%e\t%e\t%d\t%d", |
551 | &idManuChannel, &fLut[i].fDetElemId, &fLut[i].fIX, |
552 | &fLut[i].fIY, &fLut[i].fRealX, |
553 | &fLut[i].fRealY, &fLut[i].fRealZ, |
554 | &fLut[i].fHalfPadSize, &fLut[i].fPlane, |
555 | &fLut[i].fPed, &fLut[i].fSigma, &fLut[i].fA0, |
556 | &fLut[i].fA1, &fLut[i].fThres, &fLut[i].fSat |
557 | ); |
558 | |
559 | if (result != 15) |
560 | { |
561 | HLTError("Line %d in LUT file %s does not contain 15 elements.", i, lutFileName); |
562 | return -EIO; |
563 | } |
564 | |
565 | fIdToEntry[idManuChannel] = i; |
566 | } |
567 | |
568 | return 0; |
ee3678d3 |
569 | } |
570 | |
571 | |
93a75941 |
572 | int AliHLTMUONHitReconstructorComponent::ReadCDB(const char* cdbPath, Int_t run) |
b0201cbe |
573 | { |
93a75941 |
574 | // Reads LUT from CDB. |
575 | // TODO: merge this with CreateHitRecoLookupTables.C, make this static and use in the macro for example. |
576 | |
577 | assert( fLut == NULL ); |
578 | assert( fLutSize == 0 ); |
579 | assert( fIdToEntry.empty() ); |
580 | |
581 | std::vector<AliHLTMUONHitRecoLutRow> lutList; |
582 | AliHLTMUONHitRecoLutRow lut; |
583 | AliHLTUInt32_t iEntry = 0; |
584 | |
585 | Bool_t warn = kFALSE; |
586 | |
587 | AliCDBManager* cdbManager = AliCDBManager::Instance(); |
588 | if (cdbManager == NULL) |
589 | { |
590 | HLTError("CDB manager instance does not exist."); |
591 | return -EIO; |
592 | } |
593 | |
594 | const char* cdbPathUsed = "unknown (not set)"; |
595 | if (cdbPath != NULL) |
596 | { |
597 | cdbManager->SetDefaultStorage(cdbPath); |
598 | cdbPathUsed = cdbPath; |
599 | } |
600 | else |
601 | { |
602 | AliCDBStorage* store = cdbManager->GetDefaultStorage(); |
603 | if (store != NULL) cdbPathUsed = store->GetURI().Data(); |
604 | } |
605 | |
606 | if (run != -1) cdbManager->SetRun(run); |
607 | Int_t runUsed = cdbManager->GetRun(); |
608 | |
609 | if (not AliMpCDB::LoadDDLStore(warn)) |
610 | { |
611 | HLTError("Failed to load DDL store specified for CDB path '%s' and run no. %d", |
612 | cdbPathUsed, runUsed |
613 | ); |
614 | return -ENOENT; |
615 | } |
616 | AliMpDDLStore* ddlStore = AliMpDDLStore::Instance(); |
617 | if (ddlStore == NULL) |
618 | { |
619 | HLTError("Could not find DDL store instance."); |
620 | return -EIO; |
621 | } |
622 | AliMpSegmentation* mpSegFactory = AliMpSegmentation::Instance(); |
623 | if (mpSegFactory == NULL) |
624 | { |
625 | HLTError("Could not find segmentation mapping (AliMpSegmentation) instance."); |
626 | return -EIO; |
627 | } |
628 | |
629 | AliGeomManager::LoadGeometry(); |
630 | AliMUONGeometryTransformer chamberGeometryTransformer; |
631 | if (not chamberGeometryTransformer.LoadGeometryData()) |
632 | { |
633 | HLTError("Failed to load geomerty data."); |
634 | return -ENOENT; |
635 | } |
636 | |
637 | AliMUONCalibrationData calibData(run); |
638 | |
639 | Int_t chamberId; |
640 | |
641 | for(Int_t iCh = 6; iCh < 10; iCh++) |
642 | { |
643 | chamberId = iCh; |
644 | |
645 | AliMpDEIterator it; |
646 | for ( it.First(chamberId); ! it.IsDone(); it.Next() ) |
647 | { |
648 | Int_t detElemId = it.CurrentDEId(); |
649 | int iDDL = ddlStore->GetDetElement(detElemId)->GetDdlId(); |
650 | if (iDDL != fDDL) continue; |
651 | |
652 | for (Int_t iCath = 0 ; iCath <= 1 ; iCath++) |
653 | { |
654 | AliMp::CathodType cath; |
655 | |
656 | if(iCath == 0) |
657 | cath = AliMp::kCath0; |
658 | else |
659 | cath = AliMp::kCath1; |
660 | |
661 | const AliMpVSegmentation* seg = mpSegFactory->GetMpSegmentation(detElemId, cath); |
662 | AliMp::PlaneType plane = seg->PlaneType(); |
663 | Int_t maxIX = seg->MaxPadIndexX(); |
664 | Int_t maxIY = seg->MaxPadIndexY(); |
665 | |
666 | Int_t idManuChannel, manuId, channelId, buspatchId; |
667 | AliHLTFloat32_t padSizeX, padSizeY; |
668 | AliHLTFloat32_t halfPadSize; |
669 | Double_t realX, realY, realZ; |
670 | Double_t localX, localY, localZ; |
671 | Float_t calibA0Coeff,calibA1Coeff,pedestal,sigma; |
672 | Int_t thresold,saturation; |
673 | |
674 | // Pad Info of a slat to print in lookuptable |
675 | for (Int_t iX = 0; iX<= maxIX ; iX++) |
676 | for (Int_t iY = 0; iY<= maxIY ; iY++) |
677 | { |
678 | if (not seg->HasPad(AliMpIntPair(iX,iY))) continue; |
679 | |
680 | AliMpPad pad = seg->PadByIndices(AliMpIntPair(iX,iY), kFALSE); |
681 | |
682 | // Getting Manu id |
683 | manuId = pad.GetLocation().GetFirst(); |
684 | manuId &= 0x7FF; // 11 bits |
685 | |
686 | buspatchId = ddlStore->GetBusPatchId(detElemId,manuId); |
687 | |
688 | // Getting channel id |
689 | channelId = pad.GetLocation().GetSecond(); |
690 | channelId &= 0x3F; // 6 bits |
691 | |
692 | idManuChannel = buspatchId << 11; |
693 | idManuChannel = (idManuChannel | manuId) << 6; |
694 | idManuChannel |= channelId; |
695 | |
696 | localX = pad.Position().X(); |
697 | localY = pad.Position().Y(); |
698 | localZ = 0.0; |
699 | |
700 | chamberGeometryTransformer.Local2Global( |
701 | detElemId,localX,localY,localZ, |
702 | realX,realY,realZ |
703 | ); |
704 | |
705 | padSizeX = pad.Dimensions().X(); |
706 | padSizeY = pad.Dimensions().Y(); |
707 | |
708 | calibA0Coeff = (calibData.Gains(detElemId, manuId))->ValueAsFloat(channelId, 0); |
709 | calibA1Coeff = (calibData.Gains(detElemId, manuId))->ValueAsFloat(channelId, 1); |
710 | thresold = (calibData.Gains(detElemId, manuId))->ValueAsInt(channelId, 2); |
711 | saturation = (calibData.Gains(detElemId, manuId))->ValueAsInt(channelId, 4); |
712 | |
713 | pedestal = (calibData.Pedestals(detElemId, manuId))->ValueAsFloat(channelId, 0); |
714 | sigma = (calibData.Pedestals(detElemId, manuId))->ValueAsFloat(channelId, 1); |
715 | |
716 | if (plane == 0) |
717 | halfPadSize = padSizeX; |
718 | else |
719 | halfPadSize = padSizeY; |
720 | |
721 | fIdToEntry[idManuChannel] = iEntry+1; |
722 | |
723 | lut.fDetElemId = detElemId; |
724 | lut.fIX = iX; |
725 | lut.fIY = iY; |
726 | lut.fRealX = realX; |
727 | lut.fRealY = realY; |
728 | lut.fRealZ = realZ; |
729 | lut.fHalfPadSize = halfPadSize; |
730 | lut.fPlane = plane; |
731 | lut.fPed = pedestal; |
732 | lut.fSigma = sigma; |
733 | lut.fA0 = calibA0Coeff; |
734 | lut.fA1 = calibA1Coeff; |
735 | lut.fThres = thresold; |
736 | lut.fSat = saturation; |
737 | |
738 | lutList.push_back(lut); |
739 | iEntry++; |
740 | } // iX, iY loop |
741 | } // iCath loop |
742 | } // detElemId loop |
743 | } // ichamber loop |
744 | |
745 | try |
746 | { |
747 | // Use iEntry+1 since we add one extra LUT line for the first element |
748 | // which is used as a sentinel value. |
749 | fLut = new AliHLTMUONHitRecoLutRow[iEntry+1]; |
750 | fLutSize = iEntry+1; |
751 | } |
752 | catch (const std::bad_alloc&) |
753 | { |
754 | HLTError("Could not allocate more memory for the lookuptable."); |
755 | return -ENOMEM; |
756 | } |
757 | |
758 | // Initialise the sentinel value. |
759 | fLut[0].fDetElemId = 0; |
760 | fLut[0].fIX = 0; |
761 | fLut[0].fIY = 0; |
762 | fLut[0].fRealX = 0.0; |
763 | fLut[0].fRealY = 0.0; |
764 | fLut[0].fRealZ = 0.0; |
765 | fLut[0].fHalfPadSize = 0.0; |
766 | fLut[0].fPlane = -1; |
767 | fLut[0].fPed = -1; |
768 | fLut[0].fSigma = -1; |
769 | fLut[0].fA0 = -1; |
770 | fLut[0].fA1 = -1; |
771 | fLut[0].fThres = -1; |
772 | fLut[0].fSat = -1; |
773 | |
774 | for (AliHLTUInt32_t i = 0; i < iEntry; i++) |
775 | fLut[i+1] = lutList[i]; |
776 | |
777 | return 0; |
b0201cbe |
778 | } |
779 | |
b0201cbe |
780 | |
93a75941 |
781 | bool AliHLTMUONHitReconstructorComponent::GenerateLookupTable( |
782 | AliHLTInt32_t ddl, const char* filename, |
ee3678d3 |
783 | const char* cdbPath, Int_t run |
784 | ) |
b0201cbe |
785 | { |
93a75941 |
786 | /// Generates a ASCII text file containing the lookup table (LUT) from |
787 | /// the CDB, which can be used for the hit reconstructor component later. |
788 | /// @param ddl Must be the DDL for which to generate the DDL, |
789 | /// in the range [13..20]. |
790 | /// @param filename The name of the LUT file to generate. |
791 | /// @param cdbPath The CDB path to use. |
792 | /// @param run The run number to use for the CDB. |
793 | /// @return True if the generation of the LUT file succeeded. |
794 | |
795 | AliHLTMUONHitReconstructorComponent comp; |
796 | |
797 | if (ddl < 12 or 19 < ddl) |
798 | { |
799 | std::cerr << "ERROR: the DDL number must be in the range [12..19]." << std::endl; |
800 | return false; |
801 | } |
802 | |
803 | comp.fDDL = ddl; |
804 | if (comp.ReadCDB(cdbPath, run) != 0) return false; |
805 | |
806 | char str[1024*4]; |
807 | std::fstream file(filename, std::ios::out); |
808 | if (not file) |
809 | { |
810 | std::cerr << "ERROR: could not open file: " << filename << std::endl; |
811 | return false; |
812 | } |
813 | |
814 | assert( comp.fLut != NULL ); |
815 | |
816 | for (IdManuChannelToEntry::iterator id = comp.fIdToEntry.begin(); |
817 | id != comp.fIdToEntry.end(); |
818 | id++ |
819 | ) |
820 | { |
821 | AliHLTInt32_t idManuChannel = id->first; |
822 | AliHLTInt32_t row = id->second; |
ee3678d3 |
823 | |
93a75941 |
824 | assert( row < comp.fLutSize ); |
ee3678d3 |
825 | |
93a75941 |
826 | 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", |
827 | idManuChannel, comp.fLut[row].fDetElemId, comp.fLut[row].fIX, |
828 | comp.fLut[row].fIY, comp.fLut[row].fRealX, |
829 | comp.fLut[row].fRealY, comp.fLut[row].fRealZ, |
830 | comp.fLut[row].fHalfPadSize, comp.fLut[row].fPlane, |
831 | comp.fLut[row].fPed, comp.fLut[row].fSigma, comp.fLut[row].fA0, |
832 | comp.fLut[row].fA1, comp.fLut[row].fThres, comp.fLut[row].fSat |
833 | ); |
ee3678d3 |
834 | |
93a75941 |
835 | file << str << endl; |
836 | if (file.fail()) |
837 | { |
838 | std::cerr << "ERROR: There was an I/O error when writing to the file: " |
839 | << filename << std::endl; |
840 | return false; |
841 | } |
842 | } |
843 | |
844 | return true; |
b0201cbe |
845 | } |