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