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