Fix to be able to work with CDH v2 still...
[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  *   Artur Szostak <artursz@iafrica.com>                                  *
8  *                                                                        *
9  * Permission to use, copy, modify and distribute this software and its   *
10  * documentation strictly for non-commercial purposes is hereby granted   *
11  * without fee, provided that the above copyright notice appears in all   *
12  * copies and that both the copyright notice and this permission notice   *
13  * appear in the supporting documentation. The authors make no claims     *
14  * about the suitability of this software for any purpose. It is          *
15  * provided "as is" without express or implied warranty.                  *
16  **************************************************************************/
17
18 // $Id$
19
20 ///
21 ///  @file   AliHLTMUONHitReconstructorComponent.cxx
22 ///  @author Indranil Das <indra.das@saha.ac.in> | <indra.ehep@gmail.com>, Artur Szostak <artursz@iafrica.com>
23 ///  @date   28 May 2007
24 ///  @brief  Implementation of the hit Reconstruction processing component.
25 ///
26 ///  The HitRec Component is designed to deal the rawdata inputfiles to findout the 
27 ///  the reconstructed hits. The output is send to the output block for further 
28 ///  processing.
29 ///
30 ///  Author : Indranil Das ( indra.das@saha.ac.in || indra.ehep@gmail.com )
31 ///
32
33 #include "AliHLTMUONRecHitsBlockStruct.h"
34 #include "AliHLTMUONHitReconstructorComponent.h"
35 #include "AliHLTMUONHitReconstructor.h"
36 #include "AliHLTMUONConstants.h"
37 #include "AliHLTMUONUtils.h"
38 #include "AliHLTMUONDataBlockWriter.h"
39 #include "AliHLTMUONHitReconstructor.h"
40 #include "AliHLTLogging.h"
41 #include "AliHLTSystem.h"
42 #include "AliHLTDefinitions.h"
43 #include "AliHLTCDHWrapper.h"
44 #include <cstdlib>
45 #include <cerrno>
46 #include <cassert>
47 #include <fstream>
48
49 #include "TMap.h"
50
51 //STEER
52 #include "AliCDBManager.h"
53 #include "AliGeomManager.h"
54
55 //MUON
56 #include "AliMUONGeometryTransformer.h"
57 #include "AliMUONCalibrationData.h"
58 #include "AliMUONVCalibParam.h"
59
60 //MUON/mapping
61 #include "AliMpCDB.h"
62 #include "AliMpPad.h"
63 #include "AliMpSegmentation.h"
64 #include "AliMpDDLStore.h"
65 #include "AliMpDEIterator.h"
66 #include "AliMpVSegmentation.h"
67 #include "AliMpDEManager.h"
68 #include "AliMpDetElement.h"
69
70 ClassImp(AliHLTMUONHitReconstructorComponent)
71
72
73 AliHLTMUONHitReconstructorComponent::AliHLTMUONHitReconstructorComponent() :
74         AliHLTMUONProcessor(),
75         fHitRec(NULL),
76         fDDL(-1),
77         fLutSize(0),
78         fLut(NULL),
79         fIdToEntry(),
80         fMaxEntryPerBusPatch(),
81         fWarnForUnexpecedBlock(false),
82         fUseIdealGain(false),
83         fWarnIfPadSkipped(false)
84 {
85         ///
86         /// Default constructor.
87         ///
88 }
89
90
91 AliHLTMUONHitReconstructorComponent::~AliHLTMUONHitReconstructorComponent()
92 {
93         ///
94         /// Default destructor.
95         ///
96         
97         if (fHitRec != NULL)
98         {
99                 delete fHitRec;
100         }
101         if (fLut != NULL)
102         {
103                 delete [] fLut;
104         }
105 }
106
107 const char* AliHLTMUONHitReconstructorComponent::GetComponentID()
108 {
109         ///
110         /// Inherited from AliHLTComponent. Returns the component ID.
111         ///
112         
113         return AliHLTMUONConstants::HitReconstructorId();
114 }
115
116
117 void AliHLTMUONHitReconstructorComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list)
118 {
119         ///
120         /// Inherited from AliHLTProcessor. Returns the list of expected input data types.
121         ///
122         
123         list.clear();
124         list.push_back( AliHLTMUONConstants::DDLRawDataType() );
125 }
126
127
128 AliHLTComponentDataType AliHLTMUONHitReconstructorComponent::GetOutputDataType()
129 {
130         ///
131         /// Inherited from AliHLTComponent. Returns the output data type.
132         ///
133         
134         return kAliHLTMultipleDataType;
135 }
136
137
138 int AliHLTMUONHitReconstructorComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& list)
139 {
140         /// Inherited from AliHLTComponent. Returns the output data types.
141         
142         assert( list.empty() );
143         list.push_back( AliHLTMUONConstants::RecHitsBlockDataType() );
144         list.push_back( AliHLTMUONConstants::ClusterBlockDataType() );
145         list.push_back( AliHLTMUONConstants::ChannelBlockDataType() );
146         return list.size();
147 }
148
149
150 void AliHLTMUONHitReconstructorComponent::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier)
151 {
152         ///
153         /// Inherited from AliHLTComponent. Returns an estimate of the expected output data size.
154         ///
155         
156         constBase = sizeof(AliHLTMUONRecHitsBlockWriter::HeaderType) + 1024*1024;
157         inputMultiplier = 1;
158 }
159
160
161 AliHLTComponent* AliHLTMUONHitReconstructorComponent::Spawn()
162 {
163         ///
164         /// Inherited from AliHLTComponent. Creates a new object instance.
165         ///
166         
167         return new AliHLTMUONHitReconstructorComponent;
168 }
169
170
171 int AliHLTMUONHitReconstructorComponent::DoInit(int argc, const char** argv)
172 {
173         ///
174         /// Inherited from AliHLTComponent.
175         /// Parses the command line parameters and initialises the component.
176         ///
177
178         HLTInfo("Initialising dHLT hit reconstruction component.");
179
180         // Inherit the parents functionality.
181         int result = AliHLTMUONProcessor::DoInit(argc, argv);
182         if (result != 0) return result;
183         
184         // Must make sure that fHitRec and fLut is deleted if it is still
185         // allocated for whatever reason.
186         FreeMemory();
187         
188         // Initialise fields with default values then parse the command line.
189         fDDL = -1;
190         fIdToEntry.clear();
191         fMaxEntryPerBusPatch.clear();
192         fWarnForUnexpecedBlock = false;
193         fUseIdealGain = false;
194         fWarnIfPadSkipped = false;
195         const char* lutFileName = NULL;
196         bool useCDB = false;
197         typedef AliHLTMUONHitReconstructor HR;
198         HR::ERecoveryMode recoveryMode = HR::kDontTryRecover;
199         AliHLTInt32_t dccut = -1;
200         bool skipParityErrors = false;
201         bool dontPrintParityErrors = false;
202         bool makeClusters = false;
203         bool makeChannels = false;
204         
205         for (int i = 0; i < argc; i++)
206         {
207                 // To keep the legacy behaviour we need to have the following check
208                 // for -cdbpath here, before ArgumentAlreadyHandled.
209                 if (strcmp(argv[i], "-cdbpath") == 0)
210                 {
211                         useCDB = true;
212                 }
213
214                 if (ArgumentAlreadyHandled(i, argv[i])) continue;
215                 
216                 if (strcmp( argv[i], "-ddl" ) == 0)
217                 {
218                         if (fDDL != -1)
219                         {
220                                 HLTWarning("DDL number was already specified."
221                                         " Will replace previous value given by -ddl or -ddlid."
222                                 );
223                         }
224                         
225                         if (argc <= i+1)
226                         {
227                                 HLTError("The DDL number was not specified. Must be in the range [1..20].");
228                                 return -EINVAL;
229                         }
230                         
231                         char* cpErr = NULL;
232                         unsigned long num = strtoul( argv[i+1], &cpErr, 0 );
233                         if (cpErr == NULL or *cpErr != '\0')
234                         {
235                                 HLTError("Cannot convert '%s' to DDL a number.", argv[i+1] );
236                                 return -EINVAL;
237                         }
238                         if (num < 1 or 20 < num)
239                         {
240                                 HLTError("The DDL number must be in the range [1..20].");
241                                 return -EINVAL;
242                         }
243                         fDDL = num - 1;  // convert to range [0..19]
244                         
245                         i++;
246                         continue;
247                 } // -ddl argument
248                 
249                 if (strcmp( argv[i], "-ddlid" ) == 0)
250                 {
251                         if (fDDL != -1)
252                         {
253                                 HLTWarning("DDL number was already specified."
254                                         " Will replace previous value given by -ddl or -ddlid."
255                                 );
256                         }
257                         
258                         if ( argc <= i+1 )
259                         {
260                                 HLTError("DDL equipment ID number not specified. It must be in the range [2560..2579]" );
261                                 return -EINVAL;
262                         }
263                 
264                         char* cpErr = NULL;
265                         unsigned long num = strtoul(argv[i+1], &cpErr, 0);
266                         if (cpErr == NULL or *cpErr != '\0')
267                         {
268                                 HLTError("Cannot convert '%s' to a DDL equipment ID Number.", argv[i+1]);
269                                 return -EINVAL;
270                         }
271                         fDDL = AliHLTMUONUtils::EquipIdToDDLNumber(num); // Convert to DDL number in the range 0..21
272                         if (fDDL < 0 or 19 < fDDL)
273                         {
274                                 HLTError("The DDL equipment ID number must be in the range [2560..2579].");
275                                 return -EINVAL;
276                         }
277                         
278                         i++;
279                         continue;
280                 }
281                 
282                 if (strcmp( argv[i], "-lut" ) == 0)
283                 {
284                         if (lutFileName != NULL)
285                         {
286                                 HLTWarning("LUT path was already specified."
287                                         " Will replace previous value given by -lut."
288                                 );
289                         }
290                         
291                         if (argc <= i+1)
292                         {
293                                 HLTError("The lookup table filename was not specified.");
294                                 return -EINVAL;
295                         }
296                         lutFileName = argv[i+1];
297                         i++;
298                         continue;
299                 } // -lut argument
300                 
301                 if (strcmp( argv[i], "-cdb" ) == 0)
302                 {
303                         useCDB = true;
304                         continue;
305                 } // -cdb argument
306                 
307                 if (strcmp( argv[i], "-dccut" ) == 0)
308                 {
309                         if (dccut != -1)
310                         {
311                                 HLTWarning("DC cut parameter was already specified."
312                                         " Will replace previous value given by -dccut."
313                                 );
314                         }
315                         
316                         if ( argc <= i+1 )
317                         {
318                                 HLTError("No DC cut value was specified. It should be a positive integer value." );
319                                 return -EINVAL;
320                         }
321                         
322                         char* cpErr = NULL;
323                         dccut = AliHLTInt32_t( strtol(argv[i+1], &cpErr, 0) );
324                         if (cpErr == NULL or *cpErr != '\0' or dccut < 0)
325                         {
326                                 HLTError("Cannot convert '%s' to a valid DC cut value."
327                                         " Expected a positive integer value.", argv[i+1]
328                                 );
329                                 return -EINVAL;
330                         }
331                         
332                         i++;
333                         continue;
334                 }
335                 
336                 if (strcmp( argv[i], "-warn_on_unexpected_block" ) == 0)
337                 {
338                         fWarnForUnexpecedBlock = true;
339                         continue;
340                 }
341                 
342                 if (strcmp( argv[i], "-tryrecover" ) == 0)
343                 {
344                         if (argc > i+1)
345                         {
346                                 // There might be an optional parameter so check
347                                 // if it is a recognised one. If not then assume it
348                                 // is the next argument, so no error message.
349                                 if (strcmp(argv[i+1], "full") == 0)
350                                 {
351                                         recoveryMode = HR::kRecoverFull;
352                                         i++;
353                                 }
354                                 else if (strcmp(argv[i+1], "skip") == 0)
355                                 {
356                                         recoveryMode = HR::kRecoverJustSkip;
357                                         i++;
358                                 }
359                                 else if (strcmp(argv[i+1], "parityerrors") == 0)
360                                 {
361                                         recoveryMode = HR::kRecoverFromParityErrorsOnly;
362                                         i++;
363                                 }
364                                 else
365                                 {
366                                         recoveryMode = HR::kRecoverFull;
367                                 }
368                         }
369                         else
370                         {
371                                 recoveryMode = HR::kRecoverFull;
372                         }
373                         continue;
374                 }
375                 
376                 if (strcmp( argv[i], "-skipparityerrors" ) == 0)
377                 {
378                         skipParityErrors = true;
379                         continue;
380                 }
381                 
382                 if (strcmp( argv[i], "-dontprintparityerrors" ) == 0)
383                 {
384                         dontPrintParityErrors = true;
385                         continue;
386                 }
387                 
388                 if (strcmp( argv[i], "-useidealgain" ) == 0)
389                 {
390                         fUseIdealGain = true;
391                         continue;
392                 }
393                 
394                 if (strcmp( argv[i], "-makeclusters" ) == 0)
395                 {
396                         makeClusters = true;
397                         continue;
398                 }
399                 
400                 if (strcmp( argv[i], "-makechannels" ) == 0)
401                 {
402                         makeChannels = true;
403                         continue;
404                 }
405                 
406                 if (strcmp( argv[i], "-warnifpadskipped" ) == 0)
407                 {
408                         fWarnIfPadSkipped = true;
409                         continue;
410                 }
411         
412                 HLTError("Unknown option '%s'", argv[i]);
413                 return -EINVAL;
414         
415         } // for loop
416         
417         try
418         {
419                 fHitRec = new AliHLTMUONHitReconstructor();
420         }
421         catch (const std::bad_alloc&)
422         {
423                 HLTError("Could not allocate more memory for the hit reconstructor component.");
424                 return -ENOMEM;
425         }
426         
427         if (dccut != -1 and useCDB)
428         {
429                 HLTWarning("The -cdb or -cdbpath parameter was specified, which indicates that"
430                         " this component should read from the CDB, but then the -dccut argument"
431                         " was also used. Will override the value from CDB with the command"
432                         " line DC cut parameter given."
433                 );
434         }
435         
436         if (lutFileName != NULL and useCDB == true)
437         {
438                 HLTWarning("The -cdb or -cdbpath parameter was specified, which indicates that"
439                         " this component should read from the CDB, but then the -lut argument"
440                         " was also used. Will ignore the -lut option and load from CDB anyway."
441                 );
442         }
443         
444         if (lutFileName == NULL) useCDB = true;
445         
446         if (fDDL == -1 and not DelaySetup())
447         {
448                 HLTWarning("DDL number not specified. Cannot check if incomming data is valid.");
449         }
450         
451         if (useCDB)
452         {
453                 if (not DelaySetup())
454                 {
455                         HLTInfo("Loading lookup table information from CDB for DDL %d (ID = %d).",
456                                 fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL)
457                         );
458                         result = ReadLutFromCDB();
459                         if (result != 0)
460                         {
461                                 // Error messages already generated in ReadLutFromCDB.
462                                 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
463                                 return result;
464                         }
465                         fHitRec->SetLookUpTable(fLut, &fIdToEntry, &fMaxEntryPerBusPatch);
466                 }
467         }
468         else
469         {
470                 HLTInfo("Loading lookup table information from file %s.", lutFileName);
471                 result = ReadLookUpTable(lutFileName);
472                 if (result != 0)
473                 {
474                         // Error messages already generated in ReadLookUpTable.
475                         FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
476                         return result;
477                 }
478                 fHitRec->SetLookUpTable(fLut, &fIdToEntry, &fMaxEntryPerBusPatch);
479         }
480         
481         if (dccut == -1)
482         {
483                 if (not DelaySetup())
484                 {
485                         HLTInfo("Loading DC cut parameters from CDB for DDL %d (ID = %d).",
486                                 fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL)
487                         );
488                         result = ReadDCCutFromCDB();
489                         if (result != 0)
490                         {
491                                 // Error messages already generated in ReadDCCutFromCDB.
492                                 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
493                                 return result;
494                         }
495                 }
496                 else
497                 {
498                         // Print the debug messages here since ReadDCCutFromCDB does not get called,
499                         // in-which the debug messages would have been printed.
500                         HLTDebug("Using DC cut parameter of %d ADC channels.", fHitRec->GetDCCut());
501                 }
502         }
503         else
504         {
505                 fHitRec->SetDCCut(dccut);
506                 HLTDebug("Using DC cut parameter of %d ADC channels.", fHitRec->GetDCCut());
507         }
508         
509         fHitRec->TryRecover(recoveryMode);
510         fHitRec->SkipParityErrors(skipParityErrors);
511         fHitRec->DontPrintParityErrors(dontPrintParityErrors);
512         fHitRec->GenerateClusterInfo(makeClusters);
513         fHitRec->GenerateChannelInfo(makeChannels);
514         fHitRec->DDLNumber(fDDL);
515         //The DDL number has to be set before the following InitDetElemInDDLArray() method
516         fHitRec->InitDetElemInDDLArray();
517         HLTDebug("dHLT hit reconstruction component is initialized.");
518         return 0;
519 }
520
521
522 int AliHLTMUONHitReconstructorComponent::DoDeinit()
523 {
524         ///
525         /// Inherited from AliHLTComponent. Performs a cleanup of the component.
526         ///
527         fHitRec->DeInitDetElemInDDLArray();
528         HLTInfo("Deinitialising dHLT hit reconstruction component.");
529         FreeMemory();
530         return 0;
531 }
532
533
534 int AliHLTMUONHitReconstructorComponent::Reconfigure(
535                 const char* cdbEntry, const char* componentId
536         )
537 {
538         /// Inherited from AliHLTComponent. This method will reload CDB configuration
539         /// entries for this component from the CDB.
540         /// \param cdbEntry If this is NULL then it is assumed that all CDB entries should
541         ///      be reloaded. Otherwise a particular value for 'cdbEntry' will trigger
542         ///      reloading of the LUT if the path contains 'MUON/' and reloading of the DC
543         ///      cut parameter if 'cdbEntry' equals "HLT/ConfigMUON/HitReconstructor".
544         /// \param componentId  The name of the component in the current chain.
545         
546         TString path = cdbEntry;
547         bool startsWithMUON = path.Index("MUON/", 5, 0, TString::kExact) == 0;
548         bool givenConfigPath = (path == AliHLTMUONConstants::HitReconstructorCDBPath());
549         
550         if (cdbEntry == NULL or startsWithMUON or givenConfigPath)
551         {
552                 HLTInfo("Reading new configuration entries from CDB for component '%s'.", componentId);
553         }
554                 
555         if (cdbEntry == NULL or startsWithMUON)
556         {
557                 // First clear the current LUT data and then load in the new values.
558                 if (fLut != NULL)
559                 {
560                         delete [] fLut;
561                         fLut = NULL;
562                         fLutSize = 0;
563                 }
564                 
565                 fIdToEntry.clear();
566                 fMaxEntryPerBusPatch.clear();   
567                 int result = ReadLutFromCDB();
568                 if (result != 0) return result;
569                 fHitRec->SetLookUpTable(fLut, &fIdToEntry, &fMaxEntryPerBusPatch);
570         }
571         
572         if (cdbEntry == NULL or not startsWithMUON)
573         {
574                 int result = ReadDCCutFromCDB();
575                 if (result != 0) return result;
576         }
577         
578         return 0;
579 }
580
581
582 int AliHLTMUONHitReconstructorComponent::ReadPreprocessorValues(const char* modules)
583 {
584         /// Inherited from AliHLTComponent. 
585         /// Updates the configuration of this component if either HLT or MUON have
586         /// been specified in the 'modules' list.
587
588         TString mods = modules;
589         if (mods.Contains("ALL") or (mods.Contains("HLT") and mods.Contains("MUON")))
590         {
591                 return Reconfigure(NULL, GetComponentID());
592         }
593         if (mods.Contains("HLT"))
594         {
595                 return Reconfigure(AliHLTMUONConstants::HitReconstructorCDBPath(), GetComponentID());
596         }
597         if (mods.Contains("MUON"))
598         {
599                 return Reconfigure("MUON/*", GetComponentID());
600         }
601         return 0;
602 }
603
604
605 int AliHLTMUONHitReconstructorComponent::DoEvent(
606                 const AliHLTComponentEventData& evtData,
607                 const AliHLTComponentBlockData* blocks,
608                 AliHLTComponentTriggerData& trigData,
609                 AliHLTUInt8_t* outputPtr,
610                 AliHLTUInt32_t& size,
611                 AliHLTComponentBlockDataList& outputBlocks
612         )
613 {
614         ///
615         /// Inherited from AliHLTProcessor. Processes the new event data.
616         ///
617
618         // Initialise the LUT and DC cut parameter from CDB if we were requested
619         // to initialise only when the first event was received.
620         if (DelaySetup())
621         {
622                 // Use the specification given by the first data block if we
623                 // have not been given a DDL number on the command line.
624                 if (fDDL == -1)
625                 {
626                         bool blockFound = false;
627                         for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt and not blockFound; n++)
628                         {
629                                 if (blocks[n].fDataType != AliHLTMUONConstants::DDLRawDataType()) continue;
630                                 blockFound = true;
631
632                                 fDDL = AliHLTMUONUtils::SpecToDDLNumber(blocks[n].fSpecification);
633                                 
634                                 if (fDDL == -1)
635                                 {
636                                         HLTError("Received a data block with a specification (0x%8.8X)"
637                                                 " indicating multiple DDL data sources, but we must only"
638                                                 " receive raw DDL data from one tracking station DDL.",
639                                                 blocks[n].fSpecification
640                                         );
641                                         return -EPROTO;
642                                 }
643                         }
644
645                         if (not blockFound)
646                         {
647                                 HLTError("The initialisation from CDB of the component has"
648                                         " been delayed to the first received event. However,"
649                                         " no raw DDL data blocks have been found in the first event."
650                                 );
651                                 return -ENOENT;
652                         }
653                 }
654                 
655                 // Check that the LUT was not already loaded in DoInit.
656                 if (fLut == NULL)
657                 {
658                         HLTInfo("Loading lookup table information from CDB for DDL %d (ID = %d).",
659                                 fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL)
660                         );
661                         int result = ReadLutFromCDB();
662                         if (result != 0) return result;
663                         
664                         fHitRec->SetLookUpTable(fLut, &fIdToEntry, &fMaxEntryPerBusPatch);
665                 }
666                 
667                 // Check that the DC cut was not already loaded in DoInit.
668                 if (fHitRec->GetDCCut() == -1)
669                 {
670                         HLTInfo("Loading DC cut parameters from CDB for DDL %d (ID = %d).",
671                                 fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL)
672                         );
673                         int result = ReadDCCutFromCDB();
674                         if (result != 0) return result;
675                 }
676                 
677                 DoneDelayedSetup();
678         }
679         
680         if (fLut == NULL)
681         {
682                 HLTFatal("Lookup table not loaded! Cannot continue processing data.");
683                 return -ENOENT;
684         }
685         
686         // Process an event
687         unsigned long totalSize = 0; // Amount of memory currently consumed in bytes.
688
689         HLTDebug("Processing event %llu with %u input data blocks.",
690                 evtData.fEventID, evtData.fBlockCnt
691         );
692
693         // Loop over all input blocks in the event
694         for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
695         {
696                 HLTDebug("Handling block: %u, with fDataType = '%s', fPtr = %p and fSize = %u bytes.",
697                         n, DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fPtr, blocks[n].fSize
698                 );
699
700                 if (blocks[n].fDataType != AliHLTMUONConstants::DDLRawDataType()
701                     or not AliHLTMUONUtils::IsTrackerDDL(blocks[n].fSpecification)
702                    )
703                 {
704                         // Log a message indicating that we got a data block that we
705                         // do not know how to handle.
706                         if (fWarnForUnexpecedBlock)
707                                 HLTWarning("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
708                                         DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification
709                                 );
710 #ifdef __DEBUG
711                         else
712                                 HLTDebug("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
713                                         DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification
714                                 );
715 #endif
716                         
717                         continue;
718                 }
719                 
720                 if (fDDL != -1)
721                 {
722                         AliHLTInt32_t receivedDDL = AliHLTMUONUtils::SpecToDDLNumber(blocks[n].fSpecification);
723                         if (receivedDDL != fDDL)
724                         {
725                                 HLTWarning("Received raw data from DDL %d (ID = %d),"
726                                         " but expect data only from DDL %d (ID = %d).",
727                                         receivedDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(receivedDDL),
728                                         fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL)
729                                 );
730                         }
731                 }
732                 
733                 // Create a new output data block and initialise the header.
734                 AliHLTMUONRecHitsBlockWriter block(outputPtr+totalSize, size-totalSize);
735                 if (not block.InitCommonHeader())
736                 {
737                         HLTError("There is not enough space in the output buffer for the new data block."
738                                  " We require at least %u bytes, but have %u bytes left.",
739                                 sizeof(AliHLTMUONRecHitsBlockWriter::HeaderType),
740                                 block.BufferSize()
741                         );
742                         break;
743                 }
744                 
745             AliHLTCDHWrapper cdh(blocks[n].fPtr);
746
747                 AliHLTUInt32_t headerSize = cdh.GetHeaderSize();
748
749                 AliHLTUInt32_t totalDDLSize = blocks[n].fSize / sizeof(AliHLTUInt32_t);
750                 AliHLTUInt32_t ddlRawDataSize = totalDDLSize - headerSize / sizeof(AliHLTUInt32_t);
751                 AliHLTUInt32_t* buffer = reinterpret_cast<AliHLTUInt32_t*>(blocks[n].fPtr)
752     + headerSize/sizeof(AliHLTUInt32_t);
753                 AliHLTUInt32_t nofHit = block.MaxNumberOfEntries();
754
755 #ifdef DEBUG
756                 HLTDebug("=========== Dumping DDL payload buffer ==========");
757                 for (AliHLTUInt32_t j = 0; j < totalDDLSize; j++)
758                         HLTDebug("buffer[%d] : %x",j,buffer[j]);
759                 HLTDebug("================== End of dump =================");
760 #endif // DEBUG
761
762                 if (not fHitRec->Run(buffer, ddlRawDataSize, block.GetArray(), nofHit))
763                 {
764                         HLTError("Error while processing the hit reconstruction algorithm.");
765                         if (DumpDataOnError()) DumpEvent(evtData, blocks, trigData, outputPtr, size, outputBlocks);
766                         size = totalSize; // Must tell the framework how much buffer space was used.
767                         return -EIO;
768                 }
769                 
770                 // nofHit should now contain the number of reconstructed hits actually found
771                 // and filled into the output data block, so we can set this number.
772                 assert( nofHit <= block.MaxNumberOfEntries() );
773                 block.SetNumberOfEntries(nofHit);
774                 
775                 HLTDebug("Number of reconstructed hits found is %d", nofHit);
776
777                 // Fill a block data structure for our output block.
778                 AliHLTComponentBlockData bd;
779                 FillBlockData(bd);
780                 bd.fPtr = outputPtr;
781                 // This block's start (offset) is after all other blocks written so far.
782                 bd.fOffset = totalSize;
783                 bd.fSize = block.BytesUsed();
784                 bd.fDataType = AliHLTMUONConstants::RecHitsBlockDataType();
785                 bd.fSpecification = blocks[n].fSpecification;
786                 outputBlocks.push_back(bd);
787
788                 // Increase the total amount of data written so far to our output memory
789                 totalSize += block.BytesUsed();
790                 
791                 if (fHitRec->GenerateClusterInfo())
792                 {
793                         // Create a new output clusters data block and initialise the header.
794                         AliHLTMUONClustersBlockWriter clustblock(outputPtr+totalSize, size-totalSize);
795                         if (not clustblock.InitCommonHeader())
796                         {
797                                 HLTError("There is not enough space in the output buffer for the new clusters data block."
798                                         " We require at least %u bytes, but have %u bytes left.",
799                                         sizeof(AliHLTMUONClustersBlockWriter::HeaderType),
800                                         clustblock.BufferSize()
801                                 );
802                                 break;
803                         }
804                         
805                         AliHLTUInt32_t nofClusters = clustblock.MaxNumberOfEntries();
806                         bool filledOk = fHitRec->FillClusterData(clustblock.GetArray(), nofClusters);
807                         // nofClusters should now contain the number of clusters filled.
808                         assert( nofClusters <= clustblock.MaxNumberOfEntries() );
809                         clustblock.SetNumberOfEntries(nofClusters);
810                         
811                         // Fill a block data structure for our output block.
812                         AliHLTComponentBlockData bdc;
813                         FillBlockData(bdc);
814                         bdc.fPtr = outputPtr;
815                         // This block's start (offset) is after all other blocks written so far.
816                         bdc.fOffset = totalSize;
817                         bdc.fSize = clustblock.BytesUsed();
818                         bdc.fDataType = AliHLTMUONConstants::ClusterBlockDataType();
819                         bdc.fSpecification = blocks[n].fSpecification;
820                         outputBlocks.push_back(bdc);
821         
822                         // Increase the total amount of data written so far to our output memory
823                         totalSize += clustblock.BytesUsed();
824                         
825                         if (not filledOk)
826                         {
827                                 HLTError("We have overflowed the output buffer space for the new clusters data block.");
828                                 break;
829                         }
830                 }
831                 
832                 if (fHitRec->GenerateChannelInfo())
833                 {
834                         // Create a new output channels data block and initialise the header.
835                         AliHLTMUONChannelsBlockWriter channelblock(outputPtr+totalSize, size-totalSize);
836                         if (not channelblock.InitCommonHeader())
837                         {
838                                 HLTError("There is not enough space in the output buffer for the new channels data block."
839                                         " We require at least %u bytes, but have %u bytes left.",
840                                         sizeof(AliHLTMUONChannelsBlockWriter::HeaderType),
841                                         channelblock.BufferSize()
842                                 );
843                                 break;
844                         }
845                         
846                         AliHLTUInt32_t nofChannels = channelblock.MaxNumberOfEntries();
847                         bool filledOk = fHitRec->FillChannelData(channelblock.GetArray(), nofChannels);
848                         // nofChannels should now contain the number of channels filled.
849                         assert( nofChannels <= channelblock.MaxNumberOfEntries() );
850                         channelblock.SetNumberOfEntries(nofChannels);
851                         
852                         // Fill a block data structure for our output block.
853                         AliHLTComponentBlockData bdc;
854                         FillBlockData(bdc);
855                         bdc.fPtr = outputPtr;
856                         // This block's start (offset) is after all other blocks written so far.
857                         bdc.fOffset = totalSize;
858                         bdc.fSize = channelblock.BytesUsed();
859                         bdc.fDataType = AliHLTMUONConstants::ChannelBlockDataType();
860                         bdc.fSpecification = blocks[n].fSpecification;
861                         outputBlocks.push_back(bdc);
862         
863                         // Increase the total amount of data written so far to our output memory
864                         totalSize += channelblock.BytesUsed();
865                         
866                         if (not filledOk)
867                         {
868                                 HLTError("We have overflowed the output buffer space for the new channels data block.");
869                                 break;
870                         }
871                 }
872         }
873         // Finally we set the total size of output memory we consumed.
874         size = totalSize;
875
876         return 0;
877 }
878
879
880 void AliHLTMUONHitReconstructorComponent::FreeMemory()
881 {
882         /// Deletes any allocated objects if they are allocated else nothing is
883         /// done for objects not yet allocated.
884         /// This is used as a helper method to make sure the corresponding pointers
885         /// are NULL and we get back to a well defined state.
886
887         if (fHitRec != NULL)
888         {
889                 delete fHitRec;
890                 fHitRec = NULL;
891         }
892         if (fLut != NULL)
893         {
894                 delete [] fLut;
895                 fLut = NULL;
896                 fLutSize = 0;
897         }
898         
899         fIdToEntry.clear();
900         fMaxEntryPerBusPatch.clear();
901 }
902
903
904 int AliHLTMUONHitReconstructorComponent::ReadLookUpTable(const char* lutFileName)
905 {
906         /// Read in the lookup table from a text file.
907         /// Note that this method could leave fLut allocated which is cleaned up
908         /// by DoInit with a call to FreeMemory().
909         
910         assert( fLut == NULL );
911         assert( fLutSize == 0 );
912         assert( fIdToEntry.empty() );
913         assert( fMaxEntryPerBusPatch.empty() );
914         
915         std::ifstream file(lutFileName);
916         if (not file.good())
917         {
918                 HLTError("Could not open the LUT file %s", lutFileName);
919                 return -ENOENT;
920         }
921         
922         // First count the number of lines of text in the LUT file before decoding.
923         // This is not the most optimal. It would be better to read and decode at the
924         // same time but we are not allowed to use STL and ROOT containers are too
925         // heavy for this task. At least this is done only at the start of run.
926         std::string str;
927         AliHLTUInt32_t lineCount = 0;
928         while (std::getline(file, str)) lineCount++;
929         if (not file.eof())
930         {
931                 HLTError("There was a problem reading the LUT file %s", lutFileName);
932                 return -EIO;
933         }
934         if (lineCount == 0)
935         {
936                 HLTWarning("The LUT file %s was empty.", lutFileName);
937         }
938         
939         // Add one extra LUT line for the first element which is used as a sentinel value.
940         lineCount++;
941         
942         try
943         {
944                 fLut = new AliHLTMUONHitRecoLutRow[lineCount];
945                 fLutSize = lineCount;
946         }
947         catch (const std::bad_alloc&)
948         {
949                 HLTError("Could not allocate more memory for the lookuptable.");
950                 return -ENOMEM;
951         }
952         
953         // Initialise the sentinel value.
954         fLut[0].fDetElemId = 0;
955         fLut[0].fIX = 0;
956         fLut[0].fIY = 0;
957         fLut[0].fRealX = 0.0;
958         fLut[0].fRealY = 0.0;
959         fLut[0].fRealZ = 0.0;
960         fLut[0].fHalfPadSize = 0.0;
961         fLut[0].fPlane = -1;
962         fLut[0].fPed = -1;
963         fLut[0].fSigma = -1;
964         fLut[0].fA0 = -1;
965         fLut[0].fA1 = -1;
966         fLut[0].fThres = -1;
967         fLut[0].fSat = -1;
968         
969         // Clear the eof flag and start reading from the beginning of the file again.
970         file.clear();
971         file.seekg(0, std::ios::beg);
972         if (not file.good())
973         {
974                 HLTError("There was a problem seeking in the LUT file %s", lutFileName);
975                 return -EIO;
976         }
977         
978         AliHLTInt32_t idManuChannel,buspatchId;
979         for (AliHLTUInt32_t i = 1; i < fLutSize; i++)
980         {
981                 if (std::getline(file, str).fail())
982                 {
983                         HLTError("There was a problem reading line %d of LUT file %s", i, lutFileName);
984                         return -EIO;
985                 }
986                 
987                 int result = sscanf(
988                         str.c_str(), "%14d\t%14d\t%14d\t%14d\t%23e\t%23e\t%23e\t%23e\t%14d\t%23e\t%23e\t%23e\t%23e\t%14d\t%14d",
989                         &idManuChannel, &fLut[i].fDetElemId, &fLut[i].fIX,
990                         &fLut[i].fIY, &fLut[i].fRealX,
991                         &fLut[i].fRealY, &fLut[i].fRealZ,
992                         &fLut[i].fHalfPadSize, &fLut[i].fPlane,
993                         &fLut[i].fPed, &fLut[i].fSigma, &fLut[i].fA0,
994                         &fLut[i].fA1, &fLut[i].fThres, &fLut[i].fSat
995                 );
996                 
997                 if (result != 15)
998                 {
999                         HLTError("Line %d in LUT file %s does not contain 15 elements.", i, lutFileName);
1000                         return -EIO;
1001                 }
1002                 buspatchId = (idManuChannel>>17) & 0x7FF;
1003                 fIdToEntry[idManuChannel] = i;
1004                 fMaxEntryPerBusPatch[buspatchId] = fMaxEntryPerBusPatch[buspatchId] + 1;  
1005                 
1006         }
1007
1008         MaxEntryPerBusPatch::iterator it;
1009         for(it=fMaxEntryPerBusPatch.begin(); it!=fMaxEntryPerBusPatch.end(); it++){
1010                 HLTDebug("fMaxEntryPerBusPatch[%d] : %d",it->first,it->second);
1011                 fMaxEntryPerBusPatch[it->first] = AliHLTInt32_t(0.05*(it->second));///< for 10% occupancy 
1012                 HLTDebug("fMaxEntryPerBusPatch[%d] : %d",it->first,it->second);
1013         }
1014         
1015         return 0;
1016 }
1017
1018
1019 int AliHLTMUONHitReconstructorComponent::ReadLutFromCDB()
1020 {
1021         /// Reads LUT from CDB.
1022         /// To override the default CDB path and / or run number the
1023         /// SetCDBPathAndRunNo(cdbPath, run) method should be called before this
1024         /// method.
1025
1026         assert( fLut == NULL );
1027         assert( fLutSize == 0 );
1028         assert( fIdToEntry.empty() );
1029         assert( fMaxEntryPerBusPatch.empty() );
1030         
1031         if (fDDL == -1)
1032         {
1033                 HLTError("No DDL number specified for which to load LUT data from CDB.");
1034                 return -EINVAL;
1035         }
1036         
1037         std::vector<AliHLTMUONHitRecoLutRow> lutList;
1038         AliHLTMUONHitRecoLutRow lut;
1039         AliHLTUInt32_t iEntry = 0;
1040         
1041         int result = FetchMappingStores();
1042         // Error message already generated in FetchMappingStores.
1043         if (result != 0) return result;
1044         AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
1045         
1046         AliMpSegmentation* mpSegFactory = AliMpSegmentation::Instance();
1047         if (mpSegFactory == NULL)
1048         {
1049                 HLTError("Could not find segmentation mapping (AliMpSegmentation) instance.");
1050                 return -EIO;
1051         }
1052         
1053         // Only load geometry if not already loaded.
1054         if (AliGeomManager::GetGeometry() == NULL)
1055         {
1056                 AliGeomManager::LoadGeometry();
1057         }
1058         AliMUONGeometryTransformer chamberGeometryTransformer;
1059         if (not chamberGeometryTransformer.LoadGeometryData())
1060         {
1061                 HLTError("Failed to load geomerty data.");
1062                 return -ENOENT;
1063         }
1064
1065         AliMUONCalibrationData calibData(AliCDBManager::Instance()->GetRun());
1066         
1067         bool skippedPads = false;
1068         Int_t chamberId;
1069         
1070         for(Int_t iCh = 0; iCh < 10; iCh++)
1071         {
1072                 chamberId = iCh;
1073                 
1074                 AliMpDEIterator it;
1075                 for ( it.First(chamberId); ! it.IsDone(); it.Next() )
1076                 {
1077                         Int_t detElemId = it.CurrentDEId();
1078                         int iDDL = ddlStore->GetDetElement(detElemId)->GetDdlId();
1079                         if (iDDL != fDDL) continue;
1080                 
1081                         for (Int_t iCath = 0 ; iCath <= 1 ; iCath++)
1082                         {
1083                                 AliMp::CathodType cath;
1084                                 
1085                                 if(iCath == 0)
1086                                         cath = AliMp::kCath0;
1087                                 else
1088                                         cath = AliMp::kCath1;
1089                                 
1090                                 const AliMpVSegmentation* seg = mpSegFactory->GetMpSegmentation(detElemId, cath);
1091                                 AliMp::PlaneType plane = seg->PlaneType();
1092                                 Int_t maxIX = seg->MaxPadIndexX();
1093                                 Int_t maxIY = seg->MaxPadIndexY();
1094                                 
1095                                 Int_t idManuChannel, manuId, channelId, buspatchId;
1096                                 AliHLTFloat32_t padSizeX, padSizeY;
1097                                 AliHLTFloat32_t halfPadSize;
1098                                 AliHLTFloat32_t padSizeXY;
1099                                 Double_t realX, realY, realZ;
1100                                 Double_t localX, localY, localZ;
1101                                 Float_t calibA0Coeff,calibA1Coeff,pedestal,sigma;
1102                                 Float_t thresold,saturation;
1103                                 
1104                                 // Pad Info of a slat to print in lookuptable
1105                                 for (Int_t iX = 0; iX<= maxIX ; iX++)
1106                                 for (Int_t iY = 0; iY<= maxIY ; iY++)
1107                                 {
1108 #ifndef HAVE_NOT_MUON_ALIMPPAD_GETPOSITION
1109                                         if (not seg->HasPadByIndices(iX,iY)) continue;
1110 #else // old AliMpPad functionality < r 31742
1111                                         if (not seg->HasPad(AliMpIntPair(iX,iY))) continue;
1112 #endif
1113
1114 #ifndef HAVE_NOT_MUON_ALIMPPAD_GETPOSITION
1115                                         AliMpPad pad = seg->PadByIndices(iX,iY, kFALSE);
1116 #else // old AliMpPad functionality < r 31742
1117                                         AliMpPad pad = seg->PadByIndices(AliMpIntPair(iX,iY), kFALSE);
1118 #endif
1119                                         
1120                                         // Getting Manu id
1121 #ifndef HAVE_NOT_MUON_ALIMPPAD_GETPOSITION
1122                                         manuId = pad.GetManuId();
1123 #else // old AliMpPad functionality < r 31742
1124                                         manuId = pad.GetLocation().GetFirst();
1125 #endif
1126                                         manuId &= 0x7FF; // 11 bits 
1127                                         if (calibData.Gains(detElemId, manuId) == NULL) continue;
1128                                         if (calibData.Pedestals(detElemId, manuId) == NULL) continue;
1129                         
1130                                         buspatchId = ddlStore->GetBusPatchId(detElemId,manuId);
1131                                         
1132                                         // Getting channel id
1133 #ifndef HAVE_NOT_MUON_ALIMPPAD_GETPOSITION
1134                                         channelId =  pad.GetManuChannel();
1135 #else // old AliMpPad functionality < r 31742
1136                                         channelId =  pad.GetLocation().GetSecond();
1137 #endif
1138                                         channelId &= 0x3F; // 6 bits
1139                                         
1140                                         idManuChannel = buspatchId << 11;
1141                                         idManuChannel = (idManuChannel | manuId) << 6;
1142                                         idManuChannel |= channelId;
1143                                         
1144 #ifndef HAVE_NOT_MUON_ALIMPPAD_GETPOSITION
1145                                         localX = pad.GetPositionX();
1146                                         localY = pad.GetPositionY();
1147 #else // old AliMpPad functionality < r 31769
1148                                         localX = pad.Position().X();
1149                                         localY = pad.Position().Y();
1150 #endif //HAVE_NOT_MUON_ALIMPPAD_GETPOSITION
1151                                         localZ = 0.0;
1152                                         
1153                                         chamberGeometryTransformer.Local2Global(
1154                                                 detElemId,localX,localY,localZ,
1155                                                 realX,realY,realZ
1156                                         );
1157                                         
1158 #ifndef HAVE_NOT_MUON_ALIMPPAD_GETPOSITION
1159                                         padSizeX = AliHLTFloat32_t( pad.GetDimensionX() );
1160                                         padSizeY = AliHLTFloat32_t( pad.GetDimensionY() );
1161 #else // old AliMpPad functionality < r 31769
1162                                         padSizeX = AliHLTFloat32_t( pad.Dimensions().X() );
1163                                         padSizeY = AliHLTFloat32_t( pad.Dimensions().Y() );
1164 #endif //HAVE_NOT_MUON_ALIMPPAD_GETPOSITION
1165                                         
1166                                         if (fUseIdealGain)
1167                                         {
1168                                                 calibA0Coeff = 1.0;
1169                                                 calibA1Coeff = 0.0;
1170                                                 thresold = 0;
1171                                                 saturation = 0;
1172                                         }
1173                                         else
1174                                         {
1175                                                 calibA0Coeff = (calibData.Gains(detElemId, manuId))->ValueAsFloat(channelId, 0);
1176                                                 calibA1Coeff = (calibData.Gains(detElemId, manuId))->ValueAsFloat(channelId, 1);
1177                                                 thresold = (calibData.Gains(detElemId, manuId))->ValueAsFloat(channelId, 2);
1178                                                 saturation = (calibData.Gains(detElemId, manuId))->ValueAsFloat(channelId, 4);
1179                                         }
1180                                         
1181                                         pedestal = (calibData.Pedestals(detElemId, manuId))->ValueAsFloat(channelId, 0);
1182                                         sigma = (calibData.Pedestals(detElemId, manuId))->ValueAsFloat(channelId, 1);
1183                                         
1184                                         // Check if any of the values fetched from the calibration data are
1185                                         // invalid. If they are then skip this pad.
1186                                         if (calibA0Coeff == AliMUONVCalibParam::InvalidFloatValue() or
1187                                             calibA1Coeff == AliMUONVCalibParam::InvalidFloatValue() or
1188                                             thresold == AliMUONVCalibParam::InvalidFloatValue() or
1189                                             saturation == AliMUONVCalibParam::InvalidFloatValue() or
1190                                             pedestal == AliMUONVCalibParam::InvalidFloatValue() or
1191                                             sigma == AliMUONVCalibParam::InvalidFloatValue()
1192                                            )
1193                                         {
1194                                                 if (fWarnIfPadSkipped)
1195                                                 {
1196                                                         HLTWarning("Skipping pad on detection element %d, MANU %d, channel %d, since"
1197                                                                 " the calibration data contains invalid values in that channel.",
1198                                                                 detElemId, manuId, channelId
1199                                                         );
1200                                                 }
1201                                                 skippedPads = true;
1202                                                 continue;
1203                                         }
1204                                         
1205
1206                                         if (plane == 0){
1207                                                 halfPadSize = padSizeX;
1208                                                 padSizeXY = padSizeY;
1209                                         }else{
1210                                                 halfPadSize = padSizeY;
1211                                                 padSizeXY = padSizeX;
1212                                         }
1213
1214                                         fIdToEntry[idManuChannel] = iEntry+1;
1215                                         fMaxEntryPerBusPatch[buspatchId] = fMaxEntryPerBusPatch[buspatchId] + 1;  
1216                                         
1217                                         lut.fDetElemId = detElemId;
1218                                         lut.fIX = iX;
1219                                         lut.fIY = iY;
1220                                         lut.fRealX = realX;
1221                                         lut.fRealY = realY;
1222                                         lut.fRealZ = realZ;
1223                                         lut.fHalfPadSize = halfPadSize;
1224                                         lut.fPadSizeXY = padSizeXY;
1225                                         lut.fPlane = plane;
1226                                         lut.fPed = pedestal;
1227                                         lut.fSigma = sigma;
1228                                         lut.fA0 = calibA0Coeff;
1229                                         lut.fA1 = calibA1Coeff;
1230                                         lut.fThres = Int_t(thresold);
1231                                         lut.fSat = Int_t(saturation);
1232                                         
1233                                         HLTDebug("lut : detele : %d, id : %d, manu : %d, channel : %d, iX : %d, iY: %d, (X,Y) : (%f, %f), padsize : %f, plane : %d, ped : %f, sigma : %f",
1234                                                 lut.fDetElemId,idManuChannel,manuId,channelId,lut.fIX,lut.fIY,lut.fRealX,lut.fRealY,lut.fHalfPadSize,lut.fPlane,lut.fPed,lut.fSigma
1235                                         );
1236                                         
1237                                         lutList.push_back(lut);
1238                                         iEntry++;
1239                                 } // iX, iY loop
1240                         } // iCath loop
1241                 } // detElemId loop
1242         } // ichamber loop
1243         
1244         if (skippedPads and not fWarnIfPadSkipped)
1245         {
1246                 HLTWarning("Skipped pads since they contained invalid calibration values."
1247                         " Use the -warnifpadskipped argument to generate detailed information"
1248                         " about which pads were skipped."
1249                 );
1250         }
1251
1252         try
1253         {
1254                 // Use iEntry+1 since we add one extra LUT line for the first element
1255                 // which is used as a sentinel value.
1256                 fLut = new AliHLTMUONHitRecoLutRow[iEntry+1];
1257                 fLutSize = iEntry+1;
1258                 HLTDebug("Address of new LUT buffer at fLut = %p", fLut);
1259         }
1260         catch (const std::bad_alloc&)
1261         {
1262                 HLTError("Could not allocate more memory for the lookuptable.");
1263                 //lutList.clear();  not necessary, implicitly done during stack cleanup.
1264                 return -ENOMEM;
1265         }
1266         
1267         // Initialise the sentinel value.
1268         fLut[0].fDetElemId = 0;
1269         fLut[0].fIX = 0;
1270         fLut[0].fIY = 0;
1271         fLut[0].fRealX = 0.0;
1272         fLut[0].fRealY = 0.0;
1273         fLut[0].fRealZ = 0.0;
1274         fLut[0].fHalfPadSize = 0.0;
1275         fLut[0].fPadSizeXY = 0.0;
1276         fLut[0].fPlane = -1;
1277         fLut[0].fPed = -1;
1278         fLut[0].fSigma = -1;
1279         fLut[0].fA0 = -1;
1280         fLut[0].fA1 = -1;
1281         fLut[0].fThres = -1;
1282         fLut[0].fSat = -1;
1283         
1284         for (AliHLTUInt32_t i = 0; i < iEntry; i++)
1285                 fLut[i+1] = lutList[i];
1286         lutList.clear();
1287
1288         MaxEntryPerBusPatch::iterator it;
1289         for(it=fMaxEntryPerBusPatch.begin(); it!=fMaxEntryPerBusPatch.end(); it++){
1290                 HLTDebug("fMaxEntryPerBusPatch[%d] : %d",it->first,it->second);
1291                 fMaxEntryPerBusPatch[it->first] = AliHLTInt32_t(0.05*(it->second));///< for 10% occupancy
1292                 HLTDebug("fMaxEntryPerBusPatch[%d] : %d",it->first,it->second);
1293         }
1294
1295         return 0;
1296 }
1297
1298
1299 int AliHLTMUONHitReconstructorComponent::ReadDCCutFromCDB()
1300 {
1301         /// Reads the DC cut parameter from the CDB.
1302
1303         const char* pathToEntry = AliHLTMUONConstants::HitReconstructorCDBPath();
1304         
1305         TMap* map = NULL;
1306         int result = FetchTMapFromCDB(pathToEntry, map);
1307         if (result != 0) return result;
1308         
1309         Int_t value = 0;
1310         result = GetPositiveIntFromTMap(map, "dccut", value, pathToEntry, "DC cut");
1311         if (result != 0) return result;
1312         
1313         assert(fHitRec != NULL);
1314         fHitRec->SetDCCut(value);
1315         
1316         HLTDebug("Using DC cut parameter of %d ADC channels.", fHitRec->GetDCCut());
1317         
1318         return 0;
1319 }
1320
1321
1322 bool AliHLTMUONHitReconstructorComponent::GenerateLookupTable(
1323                 AliHLTInt32_t ddl, const char* filename,
1324                 const char* cdbPath, Int_t run
1325         )
1326 {
1327         /// Generates a ASCII text file containing the lookup table (LUT) from
1328         /// the CDB, which can be used for the hit reconstructor component later.
1329         /// @param ddl  Must be the DDL for which to generate the DDL,
1330         ///             in the range [0..19].
1331         /// @param filename  The name of the LUT file to generate.
1332         /// @param cdbPath  The CDB path to use.
1333         /// @param run  The run number to use for the CDB.
1334         /// @return  True if the generation of the LUT file succeeded.
1335         
1336         AliHLTMUONHitReconstructorComponent comp;
1337         
1338         if (ddl < 0 or 19 < ddl)
1339         {
1340                 std::cerr << "ERROR: the DDL number must be in the range [0..19]." << std::endl;
1341                 return false;
1342         }
1343         
1344         comp.fDDL = ddl;
1345         if (comp.SetCDBPathAndRunNo(cdbPath, run) != 0) return false;
1346         if (comp.ReadLutFromCDB() != 0) return false;
1347         
1348         char str[1024*4];
1349         std::fstream file(filename, std::ios::out);
1350         if (not file)
1351         {
1352                 std::cerr << "ERROR: could not open file: " << filename << std::endl;
1353                 return false;
1354         }
1355         
1356         assert( comp.fLut != NULL );
1357         
1358         for (IdManuChannelToEntry::iterator id = comp.fIdToEntry.begin();
1359              id != comp.fIdToEntry.end();
1360              id++
1361             )
1362         {
1363                 AliHLTInt32_t idManuChannel = id->first;
1364                 AliHLTInt32_t row = id->second;
1365                 
1366                 assert( AliHLTUInt32_t(row) < comp.fLutSize );
1367                 
1368                 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",
1369                         idManuChannel, comp.fLut[row].fDetElemId, comp.fLut[row].fIX,
1370                         comp.fLut[row].fIY, comp.fLut[row].fRealX,
1371                         comp.fLut[row].fRealY, comp.fLut[row].fRealZ,
1372                         comp.fLut[row].fHalfPadSize, comp.fLut[row].fPlane,
1373                         comp.fLut[row].fPed, comp.fLut[row].fSigma, comp.fLut[row].fA0,
1374                         comp.fLut[row].fA1, comp.fLut[row].fThres, comp.fLut[row].fSat
1375                 );
1376                 
1377                 file << str << endl;
1378                 if (file.fail())
1379                 {
1380                         std::cerr << "ERROR: There was an I/O error when writing to the file: "
1381                                 << filename << std::endl;
1382                         return false;
1383                 }
1384         }
1385         
1386         return true;
1387 }