Cleanup of documentation and code.
[u/mrichter/AliRoot.git] / HLT / MUON / OnlineAnalysis / AliHLTMUONHitReconstructorComponent.cxx
1 /**************************************************************************
2  * This file is property of and copyright by the ALICE HLT Project        * 
3  * All rights reserved.                                                   *
4  *                                                                        *
5  * Primary Authors:                                                       *
6  *   Indranil Das <indra.das@saha.ac.in>                                  *
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     *
13  * about the suitability of this software for any purpose. It is          * 
14  * provided "as is" without express or implied warranty.                  *
15  **************************************************************************/
16
17 /* $Id$ */
18
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 ///
27
28 #include "AliHLTMUONRecHitsBlockStruct.h"
29 #include "AliHLTMUONHitReconstructorComponent.h"
30 #include "AliHLTMUONHitReconstructor.h"
31 #include "AliHLTMUONConstants.h"
32 #include "AliHLTMUONUtils.h"
33 #include "AliHLTMUONDataBlockWriter.h"
34 #include "AliHLTMUONHitReconstructor.h"
35 #include "AliHLTLogging.h"
36 #include "AliHLTSystem.h"
37 #include "AliHLTDefinitions.h"
38 #include <cstdlib>
39 #include <cerrno>
40 #include <cassert>
41 #include <fstream>
42
43 //STEER 
44 #include "AliCDBManager.h"
45 #include "AliCDBStorage.h"
46 #include "AliGeomManager.h"
47
48 //MUON
49 #include "AliMUONGeometryTransformer.h"
50 #include "AliMUONCalibrationData.h"
51 #include "AliMUONVCalibParam.h"
52
53 //MUON/mapping
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
63 ClassImp(AliHLTMUONHitReconstructorComponent)
64
65
66 AliHLTMUONHitReconstructorComponent::AliHLTMUONHitReconstructorComponent() :
67         AliHLTProcessor(),
68         fHitRec(NULL),
69         fDDL(-1),
70         fLutSize(0),
71         fLut(NULL),
72         fIdToEntry(),
73         fWarnForUnexpecedBlock(false)
74 {
75         ///
76         /// Default constructor.
77         ///
78 }
79
80
81 AliHLTMUONHitReconstructorComponent::~AliHLTMUONHitReconstructorComponent()
82 {
83         ///
84         /// Default destructor.
85         ///
86         
87         if (fHitRec != NULL)
88         {
89                 delete fHitRec;
90         }
91         if (fLut != NULL)
92         {
93                 delete fLut;
94         }
95 }
96
97 const char* AliHLTMUONHitReconstructorComponent::GetComponentID()
98 {
99         ///
100         /// Inherited from AliHLTComponent. Returns the component ID.
101         ///
102         
103         return AliHLTMUONConstants::HitReconstructorId();
104 }
105
106
107 void AliHLTMUONHitReconstructorComponent::GetInputDataTypes( std::vector<AliHLTComponentDataType>& list)
108 {
109         ///
110         /// Inherited from AliHLTProcessor. Returns the list of expected input data types.
111         ///
112         
113         list.clear();
114         list.push_back( AliHLTMUONConstants::DDLRawDataType() );
115 }
116
117
118 AliHLTComponentDataType AliHLTMUONHitReconstructorComponent::GetOutputDataType()
119 {
120         ///
121         /// Inherited from AliHLTComponent. Returns the output data type.
122         ///
123         
124         return AliHLTMUONConstants::RecHitsBlockDataType();
125 }
126
127
128 void AliHLTMUONHitReconstructorComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
129 {
130         ///
131         /// Inherited from AliHLTComponent. Returns an estimate of the expected output data size.
132         ///
133         
134         constBase = sizeof(AliHLTMUONRecHitsBlockWriter::HeaderType);
135         inputMultiplier = 1;
136 }
137
138
139 AliHLTComponent* AliHLTMUONHitReconstructorComponent::Spawn()
140 {
141         ///
142         /// Inherited from AliHLTComponent. Creates a new object instance.
143         ///
144         
145         return new AliHLTMUONHitReconstructorComponent;
146 }
147
148
149 int AliHLTMUONHitReconstructorComponent::DoInit(int argc, const char** argv)
150 {
151         ///
152         /// Inherited from AliHLTComponent.
153         /// Parses the command line parameters and initialises the component.
154         ///
155
156         HLTInfo("Initialising dHLT hit reconstruction component.");
157         
158         // Must make sure that fHitRec and fLut is deleted if it is still
159         // allocated for whatever reason.
160         FreeMemory();
161         
162         try
163         {
164                 fHitRec = new AliHLTMUONHitReconstructor();
165         }
166         catch (const std::bad_alloc&)
167         {
168                 HLTError("Could not allocate more memory for the hit reconstructor component.");
169                 return -ENOMEM;
170         }
171         
172         // Initialise fields with default values then parse the command line.
173         fDDL = -1;
174         fIdToEntry.clear();
175         fWarnForUnexpecedBlock = false;
176         
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].");
191                                 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
192                                 return -EINVAL;
193                         }
194                         
195                         char* cpErr = NULL;
196                         unsigned long num = strtoul( argv[i+1], &cpErr, 0 );
197                         if (cpErr == NULL or *cpErr != '\0')
198                         {
199                                 HLTError("Cannot convert '%s' to DDL a number.", argv[i+1] );
200                                 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
201                                 return -EINVAL;
202                         }
203                         if (num < 13 or 20 < num)
204                         {
205                                 HLTError("The DDL number must be in the range [13..20].");
206                                 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
207                                 return -EINVAL;
208                         }
209                         fDDL = num - 1;  // convert to range [12..19]
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.");
220                                 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
221                                 return -EINVAL;
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." );
239                                 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
240                                 return -EINVAL;
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." );
253                                 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
254                                 return -EINVAL;
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                                 );
264                                 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
265                                 return -EINVAL;
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]);
279                 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
280                 return -EINVAL;
281         
282         } // for loop
283         
284         if (lutFileName == NULL) useCDB = true;
285         
286         if (fDDL == -1)
287         {
288                 HLTWarning("DDL number not specified. Cannot check if incomming data is valid.");
289         }
290         
291         int result = 0;
292         if (useCDB)
293         {
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);
298         }
299         else
300         {
301                 HLTInfo("Loading lookup table information from file %s.", lutFileName);
302                 result = ReadLookUpTable(lutFileName);
303         }
304         if (result != 0)
305         {
306                 // Error messages already generated in ReadCDB or ReadLookUpTable.
307                 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
308                 return result;
309         }
310         
311         fHitRec->SetLookUpTable(fLut, &fIdToEntry);
312         
313         return 0;
314 }
315
316
317 int AliHLTMUONHitReconstructorComponent::DoDeinit()
318 {
319         ///
320         /// Inherited from AliHLTComponent. Performs a cleanup of the component.
321         ///
322         
323         HLTInfo("Deinitialising dHLT hit reconstruction component.");
324         FreeMemory();
325         return 0;
326 }
327
328
329 int AliHLTMUONHitReconstructorComponent::DoEvent(
330                 const AliHLTComponentEventData& evtData,
331                 const AliHLTComponentBlockData* blocks,
332                 AliHLTComponentTriggerData& /*trigData*/,
333                 AliHLTUInt8_t* outputPtr,
334                 AliHLTUInt32_t& size,
335                 std::vector<AliHLTComponentBlockData>& outputBlocks
336         )
337 {
338         ///
339         /// Inherited from AliHLTProcessor. Processes the new event data.
340         ///
341         
342         // Process an event
343         unsigned long totalSize = 0; // Amount of memory currently consumed in bytes.
344
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 (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
351         {
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
354                 );
355
356                 if (blocks[n].fDataType != AliHLTMUONConstants::DDLRawDataType()
357                     or not AliHLTMUONUtils::IsTrackerDDL(blocks[n].fSpecification)
358                    )
359                 {
360                         // Log a message indicating that we got a data block that we
361                         // do not know how to handle.
362                         if (fWarnForUnexpecedBlock)
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
365                                 );
366                         else
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
369                                 );
370                         
371                         continue;
372                 }
373                 
374                 if (fDDL != -1)
375                 {
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                         }
382                 }
383                 
384                 // Create a new output data block and initialise the header.
385                 AliHLTMUONRecHitsBlockWriter block(outputPtr+totalSize, size-totalSize);
386                 if (not block.InitCommonHeader())
387                 {
388                         HLTError("There is not enough space in the output buffer for the new data block.",
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
402 #ifdef DEBUG
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 =================");
407 #endif // DEBUG
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.
413                         return -EIO;
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();
436         }
437         // Finally we set the total size of output memory we consumed.
438         size = totalSize;
439
440         return 0;
441 }
442
443
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
449         /// are NULL and we get back to a well defined state.
450
451         if (fHitRec != NULL)
452         {
453                 delete fHitRec;
454                 fHitRec = NULL;
455         }
456         if (fLut != NULL)
457         {
458                 delete fLut;
459                 fLut = NULL;
460                 fLutSize = 0;
461         }
462         
463         fIdToEntry.clear();
464 }
465
466
467 int AliHLTMUONHitReconstructorComponent::ReadLookUpTable(const char* lutFileName)
468 {
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;
569 }
570
571
572 int AliHLTMUONHitReconstructorComponent::ReadCDB(const char* cdbPath, Int_t run)
573 {
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;
778 }
779
780
781 bool AliHLTMUONHitReconstructorComponent::GenerateLookupTable(
782                 AliHLTInt32_t ddl, const char* filename,
783                 const char* cdbPath, Int_t run
784         )
785 {
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;
823                 
824                 assert( row < comp.fLutSize );
825                 
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                 );
834                 
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;
845 }