]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/MUON/OnlineAnalysis/AliHLTMUONHitReconstructorComponent.cxx
6b5982262b46907a74bbaf0e42584e71caa2f1e9
[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         AliHLTMUONProcessor(),
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         bool tryRecover = false;
182         
183         for (int i = 0; i < argc; i++)
184         {
185                 HLTDebug("argv[%d] == %s", i, argv[i]);
186                 
187                 if (strcmp( argv[i], "-ddl" ) == 0)
188                 {
189                         if (argc <= i+1)
190                         {
191                                 HLTError("The DDL number was not specified. Must be in the range [13..20].");
192                                 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
193                                 return -EINVAL;
194                         }
195                         
196                         char* cpErr = NULL;
197                         unsigned long num = strtoul( argv[i+1], &cpErr, 0 );
198                         if (cpErr == NULL or *cpErr != '\0')
199                         {
200                                 HLTError("Cannot convert '%s' to DDL a number.", argv[i+1] );
201                                 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
202                                 return -EINVAL;
203                         }
204                         if (num < 13 or 20 < num)
205                         {
206                                 HLTError("The DDL number must be in the range [13..20].");
207                                 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
208                                 return -EINVAL;
209                         }
210                         fDDL = num - 1;  // convert to range [12..19]
211                         
212                         i++;
213                         continue;
214                 } // -ddl argument
215                 
216                 if (strcmp( argv[i], "-lut" ) == 0)
217                 {
218                         if (argc <= i+1)
219                         {
220                                 HLTError("The lookup table filename was not specified.");
221                                 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
222                                 return -EINVAL;
223                         }
224                         lutFileName = argv[i+1];
225                         i++;
226                         continue;
227                 } // -lut argument
228                 
229                 if (strcmp( argv[i], "-cdb" ) == 0)
230                 {
231                         useCDB = true;
232                         continue;
233                 } // -cdb argument
234                 
235                 if (strcmp( argv[i], "-cdbpath" ) == 0)
236                 {
237                         if ( argc <= i+1 )
238                         {
239                                 HLTError("The CDB path was not specified." );
240                                 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
241                                 return -EINVAL;
242                         }
243                         cdbPath = argv[i+1];
244                         useCDB = true;
245                         i++;
246                         continue;
247                 } // -cdb argument
248         
249                 if (strcmp( argv[i], "-run" ) == 0)
250                 {
251                         if ( argc <= i+1 )
252                         {
253                                 HLTError("The RUN number was not specified." );
254                                 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
255                                 return -EINVAL;
256                         }
257                         
258                         char* cpErr = NULL;
259                         run = Int_t( strtoul(argv[i+1], &cpErr, 0) );
260                         if (cpErr == NULL or *cpErr != '\0')
261                         {
262                                 HLTError("Cannot convert '%s' to a valid run number."
263                                         " Expected an integer value.", argv[i+1]
264                                 );
265                                 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
266                                 return -EINVAL;
267                         }
268                         
269                         i++;
270                         continue;
271                 } // -run argument
272                 
273                 if (strcmp( argv[i], "-warn_on_unexpected_block" ) == 0)
274                 {
275                         fWarnForUnexpecedBlock = true;
276                         continue;
277                 }
278                 
279                 if (strcmp( argv[i], "-tryrecover" ) == 0)
280                 {
281                         tryRecover = true;
282                         continue;
283                 }
284         
285                 HLTError("Unknown option '%s'", argv[i]);
286                 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
287                 return -EINVAL;
288         
289         } // for loop
290         
291         if (lutFileName == NULL) useCDB = true;
292         
293         if (fDDL == -1)
294         {
295                 HLTWarning("DDL number not specified. Cannot check if incomming data is valid.");
296         }
297         
298         int result = 0;
299         if (useCDB)
300         {
301                 HLTInfo("Loading lookup table information from CDB for DDL %d.", fDDL+1);
302                 if (fDDL == -1)
303                         HLTWarning("DDL number not specified. The lookup table loaded from CDB will be empty!");
304                 result = ReadCDB(cdbPath, run);
305         }
306         else
307         {
308                 HLTInfo("Loading lookup table information from file %s.", lutFileName);
309                 result = ReadLookUpTable(lutFileName);
310         }
311         if (result != 0)
312         {
313                 // Error messages already generated in ReadCDB or ReadLookUpTable.
314                 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
315                 return result;
316         }
317         
318         fHitRec->SetLookUpTable(fLut, &fIdToEntry);
319         fHitRec->TryRecover(tryRecover);
320         
321         return 0;
322 }
323
324
325 int AliHLTMUONHitReconstructorComponent::DoDeinit()
326 {
327         ///
328         /// Inherited from AliHLTComponent. Performs a cleanup of the component.
329         ///
330         
331         HLTInfo("Deinitialising dHLT hit reconstruction component.");
332         FreeMemory();
333         return 0;
334 }
335
336
337 int AliHLTMUONHitReconstructorComponent::DoEvent(
338                 const AliHLTComponentEventData& evtData,
339                 const AliHLTComponentBlockData* blocks,
340                 AliHLTComponentTriggerData& /*trigData*/,
341                 AliHLTUInt8_t* outputPtr,
342                 AliHLTUInt32_t& size,
343                 std::vector<AliHLTComponentBlockData>& outputBlocks
344         )
345 {
346         ///
347         /// Inherited from AliHLTProcessor. Processes the new event data.
348         ///
349         
350         // Process an event
351         unsigned long totalSize = 0; // Amount of memory currently consumed in bytes.
352
353         HLTDebug("Processing event %llu with %u input data blocks.",
354                 evtData.fEventID, evtData.fBlockCnt
355         );
356
357         // Loop over all input blocks in the event
358         for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
359         {
360                 HLTDebug("Handling block: %u, with fDataType = '%s', fPtr = %p and fSize = %u bytes.",
361                         n, DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fPtr, blocks[n].fSize
362                 );
363
364                 if (blocks[n].fDataType != AliHLTMUONConstants::DDLRawDataType()
365                     or not AliHLTMUONUtils::IsTrackerDDL(blocks[n].fSpecification)
366                    )
367                 {
368                         // Log a message indicating that we got a data block that we
369                         // do not know how to handle.
370                         if (fWarnForUnexpecedBlock)
371                                 HLTWarning("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
372                                         DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification
373                                 );
374                         else
375                                 HLTDebug("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
376                                         DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification
377                                 );
378                         
379                         continue;
380                 }
381                 
382                 if (fDDL != -1)
383                 {
384                         if (AliHLTMUONUtils::SpecToDDLNumber(blocks[n].fSpecification) != fDDL)
385                         {
386                                 HLTWarning("Received raw data from an unexpected DDL.");
387                         }
388                 }
389                 
390                 // Create a new output data block and initialise the header.
391                 AliHLTMUONRecHitsBlockWriter block(outputPtr+totalSize, size-totalSize);
392                 if (not block.InitCommonHeader())
393                 {
394                         HLTError("There is not enough space in the output buffer for the new data block."
395                                  " We require at least %u bytes, but have %u bytes left.",
396                                 sizeof(AliHLTMUONRecHitsBlockWriter::HeaderType),
397                                 block.BufferSize()
398                         );
399                         break;
400                 }
401                 
402                 AliHLTUInt32_t totalDDLSize = blocks[n].fSize / sizeof(AliHLTUInt32_t);
403                 AliHLTUInt32_t ddlRawDataSize = totalDDLSize - fHitRec->GetkDDLHeaderSize();
404                 AliHLTUInt32_t* buffer = reinterpret_cast<AliHLTUInt32_t*>(blocks[n].fPtr)
405                         + fHitRec->GetkDDLHeaderSize();
406                 AliHLTUInt32_t nofHit = block.MaxNumberOfEntries();
407
408 #ifdef DEBUG
409                 HLTDebug("=========== Dumping DDL payload buffer ==========");
410                 for (AliHLTUInt32_t j = 0; j < totalDDLSize; j++)
411                         HLTDebug("buffer[%d] : %x",j,buffer[j]);
412                 HLTDebug("================== End of dump =================");
413 #endif // DEBUG
414
415                 if (not fHitRec->Run(buffer, ddlRawDataSize, block.GetArray(), nofHit))
416                 {
417                         HLTError("Error while processing the hit reconstruction algorithm.");
418                         size = totalSize; // Must tell the framework how much buffer space was used.
419                         return -EIO;
420                 }
421                 
422                 // nofHit should now contain the number of reconstructed hits actually found
423                 // and filled into the output data block, so we can set this number.
424                 assert( nofHit <= block.MaxNumberOfEntries() );
425                 block.SetNumberOfEntries(nofHit);
426                 
427                 HLTDebug("Number of reconstructed hits found is %d", nofHit);
428
429                 // Fill a block data structure for our output block.
430                 AliHLTComponentBlockData bd;
431                 FillBlockData(bd);
432                 bd.fPtr = outputPtr;
433                 // This block's start (offset) is after all other blocks written so far.
434                 bd.fOffset = totalSize;
435                 bd.fSize = block.BytesUsed();
436                 bd.fDataType = AliHLTMUONConstants::RecHitsBlockDataType();
437                 bd.fSpecification = blocks[n].fSpecification;
438                 outputBlocks.push_back(bd);
439
440                 // Increase the total amount of data written so far to our output memory
441                 totalSize += block.BytesUsed();
442         }
443         // Finally we set the total size of output memory we consumed.
444         size = totalSize;
445
446         return 0;
447 }
448
449
450 void AliHLTMUONHitReconstructorComponent::FreeMemory()
451 {
452         /// Deletes any allocated objects if they are allocated else nothing is
453         /// done for objects not yet allocated.
454         /// This is used as a helper method to make sure the corresponding pointers
455         /// are NULL and we get back to a well defined state.
456
457         if (fHitRec != NULL)
458         {
459                 delete fHitRec;
460                 fHitRec = NULL;
461         }
462         if (fLut != NULL)
463         {
464                 delete [] fLut;
465                 fLut = NULL;
466                 fLutSize = 0;
467         }
468         
469         fIdToEntry.clear();
470 }
471
472
473 int AliHLTMUONHitReconstructorComponent::ReadLookUpTable(const char* lutFileName)
474 {
475         /// Read in the lookup table from a text file.
476         /// Note that this method could leave fLut allocated which is cleaned up
477         /// by DoInit with a call to FreeMemory().
478         
479         assert( fLut == NULL );
480         assert( fLutSize == 0 );
481         assert( fIdToEntry.empty() );
482         
483         std::ifstream file(lutFileName);
484         if (not file.good())
485         {
486                 HLTError("Could not open the LUT file %s", lutFileName);
487                 return -ENOENT;
488         }
489         
490         // First count the number of lines of text in the LUT file before decoding.
491         // This is not the most optimal. It would be better to read and decode at the
492         // same time but we are not allowed to use STL and ROOT containers are too
493         // heavy for this task. At least this is done only at the start of run.
494         std::string str;
495         AliHLTUInt32_t lineCount = 0;
496         while (std::getline(file, str)) lineCount++;
497         if (not file.eof())
498         {
499                 HLTError("There was a problem reading the LUT file %s", lutFileName);
500                 return -EIO;
501         }
502         if (lineCount == 0)
503         {
504                 HLTWarning("The LUT file %s was empty.", lutFileName);
505         }
506         
507         // Add one extra LUT line for the first element which is used as a sentinel value.
508         lineCount++;
509         
510         try
511         {
512                 fLut = new AliHLTMUONHitRecoLutRow[lineCount];
513                 fLutSize = lineCount;
514         }
515         catch (const std::bad_alloc&)
516         {
517                 HLTError("Could not allocate more memory for the lookuptable.");
518                 return -ENOMEM;
519         }
520         
521         // Initialise the sentinel value.
522         fLut[0].fDetElemId = 0;
523         fLut[0].fIX = 0;
524         fLut[0].fIY = 0;
525         fLut[0].fRealX = 0.0;
526         fLut[0].fRealY = 0.0;
527         fLut[0].fRealZ = 0.0;
528         fLut[0].fHalfPadSize = 0.0;
529         fLut[0].fPlane = -1;
530         fLut[0].fPed = -1;
531         fLut[0].fSigma = -1;
532         fLut[0].fA0 = -1;
533         fLut[0].fA1 = -1;
534         fLut[0].fThres = -1;
535         fLut[0].fSat = -1;
536         
537         // Clear the eof flag and start reading from the beginning of the file again.
538         file.clear();
539         file.seekg(0, std::ios::beg);
540         if (not file.good())
541         {
542                 HLTError("There was a problem seeking in the LUT file %s", lutFileName);
543                 return -EIO;
544         }
545         
546         AliHLTInt32_t idManuChannel;
547         for (AliHLTUInt32_t i = 1; i < fLutSize; i++)
548         {
549                 if (std::getline(file, str).fail())
550                 {
551                         HLTError("There was a problem reading line %d of LUT file %s", i, lutFileName);
552                         return -EIO;
553                 }
554                 
555                 int result = sscanf(
556                         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",
557                         &idManuChannel, &fLut[i].fDetElemId, &fLut[i].fIX,
558                         &fLut[i].fIY, &fLut[i].fRealX,
559                         &fLut[i].fRealY, &fLut[i].fRealZ,
560                         &fLut[i].fHalfPadSize, &fLut[i].fPlane,
561                         &fLut[i].fPed, &fLut[i].fSigma, &fLut[i].fA0,
562                         &fLut[i].fA1, &fLut[i].fThres, &fLut[i].fSat
563                 );
564                 
565                 if (result != 15)
566                 {
567                         HLTError("Line %d in LUT file %s does not contain 15 elements.", i, lutFileName);
568                         return -EIO;
569                 }
570                 
571                 fIdToEntry[idManuChannel] = i;
572         }
573         
574         return 0;
575 }
576
577
578 int AliHLTMUONHitReconstructorComponent::ReadCDB(const char* cdbPath, Int_t run)
579 {
580         /// Reads LUT from CDB.
581
582         assert( fLut == NULL );
583         assert( fLutSize == 0 );
584         assert( fIdToEntry.empty() );
585         
586         std::vector<AliHLTMUONHitRecoLutRow> lutList;
587         AliHLTMUONHitRecoLutRow lut;
588         AliHLTUInt32_t iEntry = 0;
589         
590         int result = FetchMappingStores(cdbPath, run);
591         // Error message already generated in FetchMappingStores.
592         if (result != 0) return result;
593         AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
594         
595         AliMpSegmentation* mpSegFactory = AliMpSegmentation::Instance();
596         if (mpSegFactory == NULL)
597         {
598                 HLTError("Could not find segmentation mapping (AliMpSegmentation) instance.");
599                 return -EIO;
600         }
601         
602         // Only load geometry if not already loaded.
603         if (AliGeomManager::GetGeometry() == NULL)
604         {
605                 AliGeomManager::LoadGeometry();
606         }
607         AliMUONGeometryTransformer chamberGeometryTransformer;
608         if (not chamberGeometryTransformer.LoadGeometryData())
609         {
610                 HLTError("Failed to load geomerty data.");
611                 return -ENOENT;
612         }
613         
614         AliMUONCalibrationData calibData(run);
615         
616         Int_t chamberId;
617         
618         for(Int_t iCh = 6; iCh < 10; iCh++)
619         {
620                 chamberId = iCh;
621                 
622                 AliMpDEIterator it;
623                 for ( it.First(chamberId); ! it.IsDone(); it.Next() )
624                 {
625                         Int_t detElemId = it.CurrentDEId();
626                         int iDDL = ddlStore->GetDetElement(detElemId)->GetDdlId();
627                         if (iDDL != fDDL) continue;
628                 
629                         for (Int_t iCath = 0 ; iCath <= 1 ; iCath++)
630                         {
631                                 AliMp::CathodType cath;
632                                 
633                                 if(iCath == 0)
634                                         cath = AliMp::kCath0;
635                                 else
636                                         cath = AliMp::kCath1;
637                                 
638                                 const AliMpVSegmentation* seg = mpSegFactory->GetMpSegmentation(detElemId, cath);
639                                 AliMp::PlaneType plane = seg->PlaneType();
640                                 Int_t maxIX = seg->MaxPadIndexX();
641                                 Int_t maxIY = seg->MaxPadIndexY();
642                                 
643                                 Int_t idManuChannel, manuId, channelId, buspatchId;
644                                 AliHLTFloat32_t padSizeX, padSizeY;
645                                 AliHLTFloat32_t halfPadSize;
646                                 Double_t realX, realY, realZ;
647                                 Double_t localX, localY, localZ;
648                                 Float_t calibA0Coeff,calibA1Coeff,pedestal,sigma;
649                                 Int_t thresold,saturation;
650                                 
651                                 // Pad Info of a slat to print in lookuptable
652                                 for (Int_t iX = 0; iX<= maxIX ; iX++)
653                                 for (Int_t iY = 0; iY<= maxIY ; iY++)
654                                 {
655                                         if (not seg->HasPad(AliMpIntPair(iX,iY))) continue;
656
657                                         AliMpPad pad = seg->PadByIndices(AliMpIntPair(iX,iY), kFALSE);
658                                         
659                                         // Getting Manu id
660                                         manuId = pad.GetLocation().GetFirst();
661                                         manuId &= 0x7FF; // 11 bits 
662                         
663                                         buspatchId = ddlStore->GetBusPatchId(detElemId,manuId);
664                                         
665                                         // Getting channel id
666                                         channelId =  pad.GetLocation().GetSecond();
667                                         channelId &= 0x3F; // 6 bits
668                                         
669                                         idManuChannel = buspatchId << 11;
670                                         idManuChannel = (idManuChannel | manuId) << 6;
671                                         idManuChannel |= channelId;
672                                         
673                                         localX = pad.Position().X();
674                                         localY = pad.Position().Y();
675                                         localZ = 0.0;
676                                         
677                                         chamberGeometryTransformer.Local2Global(
678                                                 detElemId,localX,localY,localZ,
679                                                 realX,realY,realZ
680                                         );
681                                         
682                                         padSizeX = pad.Dimensions().X();
683                                         padSizeY = pad.Dimensions().Y();
684                                         
685                                         calibA0Coeff = (calibData.Gains(detElemId, manuId))->ValueAsFloat(channelId, 0);
686                                         calibA1Coeff = (calibData.Gains(detElemId, manuId))->ValueAsFloat(channelId, 1);
687                                         thresold = (calibData.Gains(detElemId, manuId))->ValueAsInt(channelId, 2);
688                                         saturation = (calibData.Gains(detElemId, manuId))->ValueAsInt(channelId, 4);
689                                         
690                                         pedestal = (calibData.Pedestals(detElemId, manuId))->ValueAsFloat(channelId, 0);
691                                         sigma = (calibData.Pedestals(detElemId, manuId))->ValueAsFloat(channelId, 1);
692                                         
693                                         if (plane == 0)
694                                                 halfPadSize = padSizeX;
695                                         else
696                                                 halfPadSize = padSizeY;
697                                         
698                                         fIdToEntry[idManuChannel] = iEntry+1;
699                         
700                                         lut.fDetElemId = detElemId;
701                                         lut.fIX = iX;
702                                         lut.fIY = iY;
703                                         lut.fRealX = realX;
704                                         lut.fRealY = realY;
705                                         lut.fRealZ = realZ;
706                                         lut.fHalfPadSize = halfPadSize;
707                                         lut.fPlane = plane;
708                                         lut.fPed = pedestal;
709                                         lut.fSigma = sigma;
710                                         lut.fA0 = calibA0Coeff;
711                                         lut.fA1 = calibA1Coeff;
712                                         lut.fThres = thresold;
713                                         lut.fSat = saturation;
714                                         
715                                         lutList.push_back(lut);
716                                         iEntry++;
717                                 } // iX, iY loop
718                         } // iCath loop
719                 } // detElemId loop
720         } // ichamber loop
721
722         try
723         {
724                 // Use iEntry+1 since we add one extra LUT line for the first element
725                 // which is used as a sentinel value.
726                 fLut = new AliHLTMUONHitRecoLutRow[iEntry+1];
727                 fLutSize = iEntry+1;
728         }
729         catch (const std::bad_alloc&)
730         {
731                 HLTError("Could not allocate more memory for the lookuptable.");
732                 return -ENOMEM;
733         }
734         
735         // Initialise the sentinel value.
736         fLut[0].fDetElemId = 0;
737         fLut[0].fIX = 0;
738         fLut[0].fIY = 0;
739         fLut[0].fRealX = 0.0;
740         fLut[0].fRealY = 0.0;
741         fLut[0].fRealZ = 0.0;
742         fLut[0].fHalfPadSize = 0.0;
743         fLut[0].fPlane = -1;
744         fLut[0].fPed = -1;
745         fLut[0].fSigma = -1;
746         fLut[0].fA0 = -1;
747         fLut[0].fA1 = -1;
748         fLut[0].fThres = -1;
749         fLut[0].fSat = -1;
750         
751         for (AliHLTUInt32_t i = 0; i < iEntry; i++)
752                 fLut[i+1] = lutList[i];
753         
754         return 0;
755 }
756
757
758 bool AliHLTMUONHitReconstructorComponent::GenerateLookupTable(
759                 AliHLTInt32_t ddl, const char* filename,
760                 const char* cdbPath, Int_t run
761         )
762 {
763         /// Generates a ASCII text file containing the lookup table (LUT) from
764         /// the CDB, which can be used for the hit reconstructor component later.
765         /// @param ddl  Must be the DDL for which to generate the DDL,
766         ///             in the range [13..20].
767         /// @param filename  The name of the LUT file to generate.
768         /// @param cdbPath  The CDB path to use.
769         /// @param run  The run number to use for the CDB.
770         /// @return  True if the generation of the LUT file succeeded.
771         
772         AliHLTMUONHitReconstructorComponent comp;
773         
774         if (ddl < 12 or 19 < ddl)
775         {
776                 std::cerr << "ERROR: the DDL number must be in the range [12..19]." << std::endl;
777                 return false;
778         }
779         
780         comp.fDDL = ddl;
781         if (comp.ReadCDB(cdbPath, run) != 0) return false;
782         
783         char str[1024*4];
784         std::fstream file(filename, std::ios::out);
785         if (not file)
786         {
787                 std::cerr << "ERROR: could not open file: " << filename << std::endl;
788                 return false;
789         }
790         
791         assert( comp.fLut != NULL );
792         
793         for (IdManuChannelToEntry::iterator id = comp.fIdToEntry.begin();
794              id != comp.fIdToEntry.end();
795              id++
796             )
797         {
798                 AliHLTInt32_t idManuChannel = id->first;
799                 AliHLTInt32_t row = id->second;
800                 
801                 assert( row < comp.fLutSize );
802                 
803                 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",
804                         idManuChannel, comp.fLut[row].fDetElemId, comp.fLut[row].fIX,
805                         comp.fLut[row].fIY, comp.fLut[row].fRealX,
806                         comp.fLut[row].fRealY, comp.fLut[row].fRealZ,
807                         comp.fLut[row].fHalfPadSize, comp.fLut[row].fPlane,
808                         comp.fLut[row].fPed, comp.fLut[row].fSigma, comp.fLut[row].fA0,
809                         comp.fLut[row].fA1, comp.fLut[row].fThres, comp.fLut[row].fSat
810                 );
811                 
812                 file << str << endl;
813                 if (file.fail())
814                 {
815                         std::cerr << "ERROR: There was an I/O error when writing to the file: "
816                                 << filename << std::endl;
817                         return false;
818                 }
819         }
820         
821         return true;
822 }