Cleaning up generation and reading back of lookup tables. Also moved core generation...
[u/mrichter/AliRoot.git] / HLT / MUON / OnlineAnalysis / AliHLTMUONHitReconstructorComponent.cxx
CommitLineData
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 63ClassImp(AliHLTMUONHitReconstructorComponent)
64
65
29486e5a 66AliHLTMUONHitReconstructorComponent::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 81AliHLTMUONHitReconstructorComponent::~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 97const 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 107void 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 118AliHLTComponentDataType 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 128void 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 139AliHLTComponent* 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 149int 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
317int 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 329int 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
350 for ( unsigned long n = 0; n < evtData.fBlockCnt; n++ )
5ff5f960 351 {
29486e5a 352#ifdef __DEBUG
353 char id[kAliHLTComponentDataTypefIDsize+1];
354 for (int i = 0; i < kAliHLTComponentDataTypefIDsize; i++)
355 id[i] = blocks[n].fDataType.fID[i];
356 id[kAliHLTComponentDataTypefIDsize] = '\0';
357 char origin[kAliHLTComponentDataTypefOriginSize+1];
358 for (int i = 0; i < kAliHLTComponentDataTypefOriginSize; i++)
359 origin[i] = blocks[n].fDataType.fOrigin[i];
360 origin[kAliHLTComponentDataTypefOriginSize] = '\0';
361#endif // __DEBUG
362 HLTDebug("Handling block: %u, with fDataType.fID = '%s',"
363 " fDataType.fID = '%s', fPtr = %p and fSize = %u bytes.",
364 n, static_cast<char*>(id), static_cast<char*>(origin),
365 blocks[n].fPtr, blocks[n].fSize
5ff5f960 366 );
29486e5a 367
668eee9f 368 if (blocks[n].fDataType != AliHLTMUONConstants::DDLRawDataType()
369 or not AliHLTMUONUtils::IsTrackerDDL(blocks[n].fSpecification)
370 )
29486e5a 371 {
372 // Log a message indicating that we got a data block that we
373 // do not know how to handle.
374 char id[kAliHLTComponentDataTypefIDsize+1];
375 for (int i = 0; i < kAliHLTComponentDataTypefIDsize; i++)
376 id[i] = blocks[n].fDataType.fID[i];
377 id[kAliHLTComponentDataTypefIDsize] = '\0';
378 char origin[kAliHLTComponentDataTypefOriginSize+1];
379 for (int i = 0; i < kAliHLTComponentDataTypefOriginSize; i++)
380 origin[i] = blocks[n].fDataType.fOrigin[i];
381 origin[kAliHLTComponentDataTypefOriginSize] = '\0';
382
383 if (fWarnForUnexpecedBlock)
668eee9f 384 HLTWarning("Received a data block of a type we cannot handle: '%s' origin: '%s' spec: 0x%X",
385 static_cast<char*>(id), static_cast<char*>(origin), blocks[n].fSpecification
29486e5a 386 );
387 else
668eee9f 388 HLTDebug("Received a data block of a type we cannot handle: '%s' origin: '%s' spec: 0x%X",
389 static_cast<char*>(id), static_cast<char*>(origin), blocks[n].fSpecification
29486e5a 390 );
391
392 continue;
393 }
394
a6b16447 395 if (fDDL != -1)
ee3678d3 396 {
a6b16447 397 bool ddl[22];
398 AliHLTMUONUtils::UnpackSpecBits(blocks[n].fSpecification, ddl);
399 if (not ddl[fDDL])
400 {
401 HLTWarning("Received raw data from an unexpected DDL.");
402 }
ee3678d3 403 }
404
29486e5a 405 // Create a new output data block and initialise the header.
406 AliHLTMUONRecHitsBlockWriter block(outputPtr+totalSize, size-totalSize);
407 if (not block.InitCommonHeader())
408 {
409 HLTError("There is not enough space in the output buffer for the new data block.",
410 " We require at least %u bytes, but have %u bytes left.",
411 sizeof(AliHLTMUONRecHitsBlockWriter::HeaderType),
412 block.BufferSize()
413 );
414 break;
415 }
416
417 AliHLTUInt32_t totalDDLSize = blocks[n].fSize / sizeof(AliHLTUInt32_t);
418 AliHLTUInt32_t ddlRawDataSize = totalDDLSize - fHitRec->GetkDDLHeaderSize();
419 AliHLTUInt32_t* buffer = reinterpret_cast<AliHLTUInt32_t*>(blocks[n].fPtr)
420 + fHitRec->GetkDDLHeaderSize();
421 AliHLTUInt32_t nofHit = block.MaxNumberOfEntries();
422
ee3678d3 423#ifdef DEBUG
29486e5a 424 HLTDebug("=========== Dumping DDL payload buffer ==========");
425 for (AliHLTUInt32_t j = 0; j < totalDDLSize; j++)
426 HLTDebug("buffer[%d] : %x",j,buffer[j]);
427 HLTDebug("================== End of dump =================");
ee3678d3 428#endif // DEBUG
29486e5a 429
430 if (not fHitRec->Run(buffer, ddlRawDataSize, block.GetArray(), nofHit))
431 {
432 HLTError("Error while processing of hit reconstruction algorithm.");
433 size = totalSize; // Must tell the framework how much buffer space was used.
a6b16447 434 return -EIO;
29486e5a 435 }
436
437 // nofHit should now contain the number of reconstructed hits actually found
438 // and filled into the output data block, so we can set this number.
439 assert( nofHit <= block.MaxNumberOfEntries() );
440 block.SetNumberOfEntries(nofHit);
441
442 HLTDebug("Number of reconstructed hits found is %d", nofHit);
443
444 // Fill a block data structure for our output block.
445 AliHLTComponentBlockData bd;
446 FillBlockData(bd);
447 bd.fPtr = outputPtr;
448 // This block's start (offset) is after all other blocks written so far.
449 bd.fOffset = totalSize;
450 bd.fSize = block.BytesUsed();
451 bd.fDataType = AliHLTMUONConstants::RecHitsBlockDataType();
452 bd.fSpecification = blocks[n].fSpecification;
453 outputBlocks.push_back(bd);
454
455 // Increase the total amount of data written so far to our output memory
456 totalSize += block.BytesUsed();
5ff5f960 457 }
29486e5a 458 // Finally we set the total size of output memory we consumed.
459 size = totalSize;
460
461 return 0;
b0201cbe 462}
463
464
a6b16447 465void AliHLTMUONHitReconstructorComponent::FreeMemory()
466{
467 /// Deletes any allocated objects if they are allocated else nothing is
468 /// done for objects not yet allocated.
469 /// This is used as a helper method to make sure the corresponding pointers
93a75941 470 /// are NULL and we get back to a well defined state.
a6b16447 471
472 if (fHitRec != NULL)
473 {
474 delete fHitRec;
475 fHitRec = NULL;
476 }
93a75941 477 if (fLut != NULL)
478 {
479 delete fLut;
480 fLut = NULL;
481 fLutSize = 0;
482 }
a6b16447 483
484 fIdToEntry.clear();
485}
486
487
93a75941 488int AliHLTMUONHitReconstructorComponent::ReadLookUpTable(const char* lutFileName)
ee3678d3 489{
93a75941 490 /// Read in the lookup table from a text file.
491 /// Note that this method could leave fLut allocated which is cleaned up
492 /// by DoInit with a call to FreeMemory().
493
494 assert( fLut == NULL );
495 assert( fLutSize == 0 );
496 assert( fIdToEntry.empty() );
497
498 std::ifstream file(lutFileName);
499 if (not file.good())
500 {
501 HLTError("Could not open the LUT file %s", lutFileName);
502 return -ENOENT;
503 }
504
505 // First count the number of lines of text in the LUT file before decoding.
506 // This is not the most optimal. It would be better to read and decode at the
507 // same time but we are not allowed to use STL and ROOT containers are too
508 // heavy for this task. At least this is done only at the start of run.
509 std::string str;
510 AliHLTUInt32_t lineCount = 0;
511 while (std::getline(file, str)) lineCount++;
512 if (not file.eof())
513 {
514 HLTError("There was a problem reading the LUT file %s", lutFileName);
515 return -EIO;
516 }
517 if (lineCount == 0)
518 {
519 HLTWarning("The LUT file %s was empty.", lutFileName);
520 }
521
522 // Add one extra LUT line for the first element which is used as a sentinel value.
523 lineCount++;
524
525 try
526 {
527 fLut = new AliHLTMUONHitRecoLutRow[lineCount];
528 fLutSize = lineCount;
529 }
530 catch (const std::bad_alloc&)
531 {
532 HLTError("Could not allocate more memory for the lookuptable.");
533 return -ENOMEM;
534 }
535
536 // Initialise the sentinel value.
537 fLut[0].fDetElemId = 0;
538 fLut[0].fIX = 0;
539 fLut[0].fIY = 0;
540 fLut[0].fRealX = 0.0;
541 fLut[0].fRealY = 0.0;
542 fLut[0].fRealZ = 0.0;
543 fLut[0].fHalfPadSize = 0.0;
544 fLut[0].fPlane = -1;
545 fLut[0].fPed = -1;
546 fLut[0].fSigma = -1;
547 fLut[0].fA0 = -1;
548 fLut[0].fA1 = -1;
549 fLut[0].fThres = -1;
550 fLut[0].fSat = -1;
551
552 // Clear the eof flag and start reading from the beginning of the file again.
553 file.clear();
554 file.seekg(0, std::ios::beg);
555 if (not file.good())
556 {
557 HLTError("There was a problem seeking in the LUT file %s", lutFileName);
558 return -EIO;
559 }
560
561 AliHLTInt32_t idManuChannel;
562 for (AliHLTUInt32_t i = 1; i < fLutSize; i++)
563 {
564 if (std::getline(file, str).fail())
565 {
566 HLTError("There was a problem reading line %d of LUT file %s", i, lutFileName);
567 return -EIO;
568 }
569
570 int result = sscanf(
571 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",
572 &idManuChannel, &fLut[i].fDetElemId, &fLut[i].fIX,
573 &fLut[i].fIY, &fLut[i].fRealX,
574 &fLut[i].fRealY, &fLut[i].fRealZ,
575 &fLut[i].fHalfPadSize, &fLut[i].fPlane,
576 &fLut[i].fPed, &fLut[i].fSigma, &fLut[i].fA0,
577 &fLut[i].fA1, &fLut[i].fThres, &fLut[i].fSat
578 );
579
580 if (result != 15)
581 {
582 HLTError("Line %d in LUT file %s does not contain 15 elements.", i, lutFileName);
583 return -EIO;
584 }
585
586 fIdToEntry[idManuChannel] = i;
587 }
588
589 return 0;
ee3678d3 590}
591
592
93a75941 593int AliHLTMUONHitReconstructorComponent::ReadCDB(const char* cdbPath, Int_t run)
b0201cbe 594{
93a75941 595 // Reads LUT from CDB.
596 // TODO: merge this with CreateHitRecoLookupTables.C, make this static and use in the macro for example.
597
598 assert( fLut == NULL );
599 assert( fLutSize == 0 );
600 assert( fIdToEntry.empty() );
601
602 std::vector<AliHLTMUONHitRecoLutRow> lutList;
603 AliHLTMUONHitRecoLutRow lut;
604 AliHLTUInt32_t iEntry = 0;
605
606 Bool_t warn = kFALSE;
607
608 AliCDBManager* cdbManager = AliCDBManager::Instance();
609 if (cdbManager == NULL)
610 {
611 HLTError("CDB manager instance does not exist.");
612 return -EIO;
613 }
614
615 const char* cdbPathUsed = "unknown (not set)";
616 if (cdbPath != NULL)
617 {
618 cdbManager->SetDefaultStorage(cdbPath);
619 cdbPathUsed = cdbPath;
620 }
621 else
622 {
623 AliCDBStorage* store = cdbManager->GetDefaultStorage();
624 if (store != NULL) cdbPathUsed = store->GetURI().Data();
625 }
626
627 if (run != -1) cdbManager->SetRun(run);
628 Int_t runUsed = cdbManager->GetRun();
629
630 if (not AliMpCDB::LoadDDLStore(warn))
631 {
632 HLTError("Failed to load DDL store specified for CDB path '%s' and run no. %d",
633 cdbPathUsed, runUsed
634 );
635 return -ENOENT;
636 }
637 AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
638 if (ddlStore == NULL)
639 {
640 HLTError("Could not find DDL store instance.");
641 return -EIO;
642 }
643 AliMpSegmentation* mpSegFactory = AliMpSegmentation::Instance();
644 if (mpSegFactory == NULL)
645 {
646 HLTError("Could not find segmentation mapping (AliMpSegmentation) instance.");
647 return -EIO;
648 }
649
650 AliGeomManager::LoadGeometry();
651 AliMUONGeometryTransformer chamberGeometryTransformer;
652 if (not chamberGeometryTransformer.LoadGeometryData())
653 {
654 HLTError("Failed to load geomerty data.");
655 return -ENOENT;
656 }
657
658 AliMUONCalibrationData calibData(run);
659
660 Int_t chamberId;
661
662 for(Int_t iCh = 6; iCh < 10; iCh++)
663 {
664 chamberId = iCh;
665
666 AliMpDEIterator it;
667 for ( it.First(chamberId); ! it.IsDone(); it.Next() )
668 {
669 Int_t detElemId = it.CurrentDEId();
670 int iDDL = ddlStore->GetDetElement(detElemId)->GetDdlId();
671 if (iDDL != fDDL) continue;
672
673 for (Int_t iCath = 0 ; iCath <= 1 ; iCath++)
674 {
675 AliMp::CathodType cath;
676
677 if(iCath == 0)
678 cath = AliMp::kCath0;
679 else
680 cath = AliMp::kCath1;
681
682 const AliMpVSegmentation* seg = mpSegFactory->GetMpSegmentation(detElemId, cath);
683 AliMp::PlaneType plane = seg->PlaneType();
684 Int_t maxIX = seg->MaxPadIndexX();
685 Int_t maxIY = seg->MaxPadIndexY();
686
687 Int_t idManuChannel, manuId, channelId, buspatchId;
688 AliHLTFloat32_t padSizeX, padSizeY;
689 AliHLTFloat32_t halfPadSize;
690 Double_t realX, realY, realZ;
691 Double_t localX, localY, localZ;
692 Float_t calibA0Coeff,calibA1Coeff,pedestal,sigma;
693 Int_t thresold,saturation;
694
695 // Pad Info of a slat to print in lookuptable
696 for (Int_t iX = 0; iX<= maxIX ; iX++)
697 for (Int_t iY = 0; iY<= maxIY ; iY++)
698 {
699 if (not seg->HasPad(AliMpIntPair(iX,iY))) continue;
700
701 AliMpPad pad = seg->PadByIndices(AliMpIntPair(iX,iY), kFALSE);
702
703 // Getting Manu id
704 manuId = pad.GetLocation().GetFirst();
705 manuId &= 0x7FF; // 11 bits
706
707 buspatchId = ddlStore->GetBusPatchId(detElemId,manuId);
708
709 // Getting channel id
710 channelId = pad.GetLocation().GetSecond();
711 channelId &= 0x3F; // 6 bits
712
713 idManuChannel = buspatchId << 11;
714 idManuChannel = (idManuChannel | manuId) << 6;
715 idManuChannel |= channelId;
716
717 localX = pad.Position().X();
718 localY = pad.Position().Y();
719 localZ = 0.0;
720
721 chamberGeometryTransformer.Local2Global(
722 detElemId,localX,localY,localZ,
723 realX,realY,realZ
724 );
725
726 padSizeX = pad.Dimensions().X();
727 padSizeY = pad.Dimensions().Y();
728
729 calibA0Coeff = (calibData.Gains(detElemId, manuId))->ValueAsFloat(channelId, 0);
730 calibA1Coeff = (calibData.Gains(detElemId, manuId))->ValueAsFloat(channelId, 1);
731 thresold = (calibData.Gains(detElemId, manuId))->ValueAsInt(channelId, 2);
732 saturation = (calibData.Gains(detElemId, manuId))->ValueAsInt(channelId, 4);
733
734 pedestal = (calibData.Pedestals(detElemId, manuId))->ValueAsFloat(channelId, 0);
735 sigma = (calibData.Pedestals(detElemId, manuId))->ValueAsFloat(channelId, 1);
736
737 if (plane == 0)
738 halfPadSize = padSizeX;
739 else
740 halfPadSize = padSizeY;
741
742 fIdToEntry[idManuChannel] = iEntry+1;
743
744 lut.fDetElemId = detElemId;
745 lut.fIX = iX;
746 lut.fIY = iY;
747 lut.fRealX = realX;
748 lut.fRealY = realY;
749 lut.fRealZ = realZ;
750 lut.fHalfPadSize = halfPadSize;
751 lut.fPlane = plane;
752 lut.fPed = pedestal;
753 lut.fSigma = sigma;
754 lut.fA0 = calibA0Coeff;
755 lut.fA1 = calibA1Coeff;
756 lut.fThres = thresold;
757 lut.fSat = saturation;
758
759 lutList.push_back(lut);
760 iEntry++;
761 } // iX, iY loop
762 } // iCath loop
763 } // detElemId loop
764 } // ichamber loop
765
766 try
767 {
768 // Use iEntry+1 since we add one extra LUT line for the first element
769 // which is used as a sentinel value.
770 fLut = new AliHLTMUONHitRecoLutRow[iEntry+1];
771 fLutSize = iEntry+1;
772 }
773 catch (const std::bad_alloc&)
774 {
775 HLTError("Could not allocate more memory for the lookuptable.");
776 return -ENOMEM;
777 }
778
779 // Initialise the sentinel value.
780 fLut[0].fDetElemId = 0;
781 fLut[0].fIX = 0;
782 fLut[0].fIY = 0;
783 fLut[0].fRealX = 0.0;
784 fLut[0].fRealY = 0.0;
785 fLut[0].fRealZ = 0.0;
786 fLut[0].fHalfPadSize = 0.0;
787 fLut[0].fPlane = -1;
788 fLut[0].fPed = -1;
789 fLut[0].fSigma = -1;
790 fLut[0].fA0 = -1;
791 fLut[0].fA1 = -1;
792 fLut[0].fThres = -1;
793 fLut[0].fSat = -1;
794
795 for (AliHLTUInt32_t i = 0; i < iEntry; i++)
796 fLut[i+1] = lutList[i];
797
798 return 0;
b0201cbe 799}
800
b0201cbe 801
93a75941 802bool AliHLTMUONHitReconstructorComponent::GenerateLookupTable(
803 AliHLTInt32_t ddl, const char* filename,
ee3678d3 804 const char* cdbPath, Int_t run
805 )
b0201cbe 806{
93a75941 807 /// Generates a ASCII text file containing the lookup table (LUT) from
808 /// the CDB, which can be used for the hit reconstructor component later.
809 /// @param ddl Must be the DDL for which to generate the DDL,
810 /// in the range [13..20].
811 /// @param filename The name of the LUT file to generate.
812 /// @param cdbPath The CDB path to use.
813 /// @param run The run number to use for the CDB.
814 /// @return True if the generation of the LUT file succeeded.
815
816 AliHLTMUONHitReconstructorComponent comp;
817
818 if (ddl < 12 or 19 < ddl)
819 {
820 std::cerr << "ERROR: the DDL number must be in the range [12..19]." << std::endl;
821 return false;
822 }
823
824 comp.fDDL = ddl;
825 if (comp.ReadCDB(cdbPath, run) != 0) return false;
826
827 char str[1024*4];
828 std::fstream file(filename, std::ios::out);
829 if (not file)
830 {
831 std::cerr << "ERROR: could not open file: " << filename << std::endl;
832 return false;
833 }
834
835 assert( comp.fLut != NULL );
836
837 for (IdManuChannelToEntry::iterator id = comp.fIdToEntry.begin();
838 id != comp.fIdToEntry.end();
839 id++
840 )
841 {
842 AliHLTInt32_t idManuChannel = id->first;
843 AliHLTInt32_t row = id->second;
ee3678d3 844
93a75941 845 assert( row < comp.fLutSize );
ee3678d3 846
93a75941 847 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",
848 idManuChannel, comp.fLut[row].fDetElemId, comp.fLut[row].fIX,
849 comp.fLut[row].fIY, comp.fLut[row].fRealX,
850 comp.fLut[row].fRealY, comp.fLut[row].fRealZ,
851 comp.fLut[row].fHalfPadSize, comp.fLut[row].fPlane,
852 comp.fLut[row].fPed, comp.fLut[row].fSigma, comp.fLut[row].fA0,
853 comp.fLut[row].fA1, comp.fLut[row].fThres, comp.fLut[row].fSat
854 );
ee3678d3 855
93a75941 856 file << str << endl;
857 if (file.fail())
858 {
859 std::cerr << "ERROR: There was an I/O error when writing to the file: "
860 << filename << std::endl;
861 return false;
862 }
863 }
864
865 return true;
b0201cbe 866}