]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/MUON/OnlineAnalysis/AliHLTMUONMansoTrackerFSMComponent.cxx
fa70206391c42dce00c4e82af394c2c6590584f8
[u/mrichter/AliRoot.git] / HLT / MUON / OnlineAnalysis / AliHLTMUONMansoTrackerFSMComponent.cxx
1 /**************************************************************************
2  * This file is property of and copyright by the ALICE HLT Project        * 
3  * All rights reserved.                                                   *
4  *                                                                        *
5  * Primary Authors:                                                       *
6  *   Artur Szostak <artursz@iafrica.com>                                  *
7  *   Indranil Das <indra.das@saha.ac.in>                                  *
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   AliHLTMUONMansoTrackerFSMComponent.cxx
22 ///  @author Artur Szostak <artursz@iafrica.com>,
23 ///          Indranil Das <indra.das@saha.ac.in>
24 ///  @date   
25 ///  @brief  Implementation of AliHLTMUONMansoTrackerFSMComponent class.
26 ///
27
28 #include "AliHLTMUONMansoTrackerFSMComponent.h"
29 #include "AliHLTMUONConstants.h"
30 #include "AliHLTMUONCalculations.h"
31 #include "AliHLTMUONUtils.h"
32 #include "AliHLTMUONMansoTrackerFSM.h"
33 #include "AliHLTMUONDataBlockReader.h"
34 #include "AliHLTMUONDataBlockWriter.h"
35 #include <cstdlib>
36 #include <cstring>
37 #include <cerrno>
38 #include <new>
39
40 ClassImp(AliHLTMUONMansoTrackerFSMComponent);
41
42
43 AliHLTMUONMansoTrackerFSMComponent::AliHLTMUONMansoTrackerFSMComponent() :
44         AliHLTMUONProcessor(),
45         AliHLTMUONMansoTrackerFSMCallback(),
46         fTracker(NULL),
47         fTrackCount(0),
48         fBlock(NULL),
49         fRecHitBlockArraySize(0),
50         fWarnForUnexpecedBlock(false),
51         fCanLoadZmiddle(true),
52         fCanLoadBL(true)
53 {
54         ///
55         /// Default constructor.
56         ///
57         
58         for (int i = 0; i < 4; i++)
59         {
60                 fRecHitBlockCount[i] = 0;
61                 fRecHitBlock[i] = NULL;
62         }
63         
64         ResetCanLoadFlags();
65 }
66
67
68 AliHLTMUONMansoTrackerFSMComponent::~AliHLTMUONMansoTrackerFSMComponent()
69 {
70         ///
71         /// Default destructor.
72         ///
73         
74         // Should never have the following 2 pointers non-NULL since DoDeinit
75         // should have been called before, but handle this case anyway.
76         if (fTracker != NULL) delete fTracker;
77         
78         // Remember that only fRecHitBlock[0] stores the pointer to the allocated
79         // memory. The other pointers are just reletive to this.
80         if (fRecHitBlock[0] != NULL) delete [] fRecHitBlock[0];
81 }
82
83
84 const char* AliHLTMUONMansoTrackerFSMComponent::GetComponentID()
85 {
86         ///
87         /// Inherited from AliHLTComponent. Returns the component ID.
88         ///
89         
90         return AliHLTMUONConstants::MansoTrackerFSMId();
91 }
92
93
94 void AliHLTMUONMansoTrackerFSMComponent::GetInputDataTypes(
95                 AliHLTComponentDataTypeList& list
96         )
97 {
98         ///
99         /// Inherited from AliHLTProcessor. Returns the list of expected input data types.
100         ///
101         
102         assert( list.empty() );
103         list.push_back( AliHLTMUONConstants::TriggerRecordsBlockDataType() );
104         list.push_back( AliHLTMUONConstants::RecHitsBlockDataType() );
105 }
106
107
108 AliHLTComponentDataType AliHLTMUONMansoTrackerFSMComponent::GetOutputDataType()
109 {
110         ///
111         /// Inherited from AliHLTComponent. Returns the output data type.
112         ///
113         
114         return AliHLTMUONConstants::MansoTracksBlockDataType();
115 }
116
117
118 void AliHLTMUONMansoTrackerFSMComponent::GetOutputDataSize(
119                 unsigned long& constBase, double& inputMultiplier
120         )
121 {
122         ///
123         /// Inherited from AliHLTComponent. Returns an estimate of the expected output data size.
124         ///
125         
126         constBase = sizeof(AliHLTMUONMansoTracksBlockStruct);
127         inputMultiplier = 1;
128 }
129
130
131 AliHLTComponent* AliHLTMUONMansoTrackerFSMComponent::Spawn()
132 {
133         ///
134         /// Inherited from AliHLTComponent. Creates a new object instance.
135         ///
136         
137         return new AliHLTMUONMansoTrackerFSMComponent;
138 }
139
140
141 int AliHLTMUONMansoTrackerFSMComponent::DoInit(int argc, const char** argv)
142 {
143         ///
144         /// Inherited from AliHLTComponent.
145         /// Parses the command line parameters and initialises the component.
146         ///
147         
148         HLTInfo("Initialising dHLT manso tracker FSM component.");
149         
150         // Inherit the parents functionality.
151         int result = AliHLTMUONProcessor::DoInit(argc, argv);
152         if (result != 0) return result;
153
154         // Just in case for whatever reason we still have some of the internal
155         // object allocated previously still hanging around delete them now.
156         FreeMemory();
157         
158         fWarnForUnexpecedBlock = false;
159         ResetCanLoadFlags();
160         double zmiddle = 0;
161         double bfieldintegral = 0;
162         double roiA[4] = {0, 0, 0, 0};
163         double roiB[4] = {0, 0, 0, 0};
164         double chamberZ[6] = {0, 0, 0, 0, 0, 0};
165         
166         for (int i = 0; i < argc; i++)
167         {
168                 if (ArgumentAlreadyHandled(i, argv[i])) continue;
169
170                 if (strcmp( argv[i], "-zmiddle" ) == 0)
171                 {
172                         if (not fCanLoadZmiddle)
173                         {
174                                 HLTWarning("The Z coordinate for the middle of the dipole was already specified."
175                                         " Will replace previous value given by -zmiddle."
176                                 );
177                         }
178                         
179                         if ( argc <= i+1 )
180                         {
181                                 HLTError("The Z coordinate for the middle of the dipole was not specified." );
182                                 return -EINVAL;
183                         }
184                         
185                         char* cpErr = NULL;
186                         zmiddle = strtod(argv[i+1], &cpErr);
187                         if (cpErr == NULL or *cpErr != '\0')
188                         {
189                                 HLTError("Cannot convert '%s' to a valid floating point number.",
190                                         argv[i+1]
191                                 );
192                                 return -EINVAL;
193                         }
194                         
195                         fCanLoadZmiddle = false;  // Prevent loading from CDB.
196                         i++;
197                         continue;
198                 }
199         
200                 if (strcmp( argv[i], "-bfieldintegral" ) == 0)
201                 {
202                         if (not fCanLoadBL)
203                         {
204                                 HLTWarning("The magnetic field integral was already specified."
205                                         " Will replace previous value given by -bfieldintegral."
206                                 );
207                         }
208                         
209                         if ( argc <= i+1 )
210                         {
211                                 HLTError("The magnetic field integral was not specified." );
212                                 return -EINVAL;
213                         }
214                         
215                         char* cpErr = NULL;
216                         bfieldintegral = strtod(argv[i+1], &cpErr);
217                         if (cpErr == NULL or *cpErr != '\0')
218                         {
219                                 HLTError("Cannot convert '%s' to a valid floating point number.",
220                                         argv[i+1]
221                                 );
222                                 return -EINVAL;
223                         }
224                         
225                         fCanLoadBL = false;  // Prevent loading from CDB.
226                         i++;
227                         continue;
228                 }
229         
230                 if (strcmp(argv[i], "-a7") == 0 or strcmp(argv[i], "-a8") == 0 or
231                     strcmp(argv[i], "-a9") == 0 or strcmp(argv[i], "-a10") == 0
232                    )
233                 {
234                         int chamber = 7; int chamberIndex = 0;
235                         switch (argv[i][2])
236                         {
237                         case '7': chamber = 7; chamberIndex = 0; break;
238                         case '8': chamber = 8; chamberIndex = 1; break;
239                         case '9': chamber = 9; chamberIndex = 2; break;
240                         case '1': chamber = 10; chamberIndex = 3; break;
241                         }
242                         
243                         if (not fCanLoadA[chamberIndex])
244                         {
245                                 HLTWarning("The region of interest parameter 'A' for chamber %d was"
246                                         " already specified. Will replace previous value given by -a%d.",
247                                         chamber, chamber
248                                 );
249                         }
250                         
251                         if ( argc <= i+1 )
252                         {
253                                 HLTError("The region of interest parameter was not specified." );
254                                 return -EINVAL;
255                         }
256                         
257                         char* cpErr = NULL;
258                         roiA[chamberIndex] = strtod(argv[i+1], &cpErr);
259                         if (cpErr == NULL or *cpErr != '\0')
260                         {
261                                 HLTError("Cannot convert '%s' to a valid floating point number.",
262                                         argv[i+1]
263                                 );
264                                 return -EINVAL;
265                         }
266                         
267                         fCanLoadA[chamberIndex] = false;  // Prevent loading from CDB.
268                         i++;
269                         continue;
270                 }
271         
272                 if (strcmp(argv[i], "-b7") == 0 or strcmp(argv[i], "-b8") == 0 or
273                     strcmp(argv[i], "-b9") == 0 or strcmp(argv[i], "-b10") == 0
274                    )
275                 {
276                         int chamber = 7; int chamberIndex = 0;
277                         switch (argv[i][2])
278                         {
279                         case '7': chamber = 7; chamberIndex = 0; break;
280                         case '8': chamber = 8; chamberIndex = 1; break;
281                         case '9': chamber = 9; chamberIndex = 2; break;
282                         case '1': chamber = 10; chamberIndex = 3; break;
283                         }
284                         
285                         if (not fCanLoadB[chamberIndex])
286                         {
287                                 HLTWarning("The region of interest parameter 'B' for chamber %d was"
288                                         " already specified. Will replace previous value given by -b%d.",
289                                         chamber, chamber
290                                 );
291                         }
292                         
293                         if ( argc <= i+1 )
294                         {
295                                 HLTError("The region of interest parameter was not specified." );
296                                 return -EINVAL;
297                         }
298                         
299                         char* cpErr = NULL;
300                         roiB[chamberIndex] = strtod(argv[i+1], &cpErr);
301                         if (cpErr == NULL or *cpErr != '\0')
302                         {
303                                 HLTError("Cannot convert '%s' to a valid floating point number.",
304                                         argv[i+1]
305                                 );
306                                 return -EINVAL;
307                         }
308                         
309                         fCanLoadB[chamberIndex] = false;  // Prevent loading from CDB.
310                         i++;
311                         continue;
312                 }
313                 
314                 if (strcmp(argv[i], "-z7") == 0 or strcmp(argv[i], "-z8") == 0 or
315                     strcmp(argv[i], "-z9") == 0 or strcmp(argv[i], "-z10") == 0 or
316                     strcmp(argv[i], "-z11") == 0 or strcmp(argv[i], "-z13") == 0
317                    )
318                 {
319                         int chamber = 7; int chamberIndex = 0;
320                         switch (argv[i][2])
321                         {
322                         case '7': chamber = 7; chamberIndex = 0; break;
323                         case '8': chamber = 8; chamberIndex = 1; break;
324                         case '9': chamber = 9; chamberIndex = 2; break;
325                         case '1':
326                                 switch (argv[i][3])
327                                 {
328                                 case '0': chamber = 10; chamberIndex = 3; break;
329                                 case '1': chamber = 11; chamberIndex = 4; break;
330                                 case '3': chamber = 13; chamberIndex = 5; break;
331                                 }
332                                 break;
333                         }
334                         
335                         if (not fCanLoadZ[chamberIndex])
336                         {
337                                 HLTWarning("The nominal Z coordinate of chamber %d was already"
338                                         " specified. Will replace previous value given by -z%d.",
339                                         chamber, chamber
340                                 );
341                         }
342                         
343                         if ( argc <= i+1 )
344                         {
345                                 HLTError("The region of interest parameter was not specified." );
346                                 return -EINVAL;
347                         }
348                         
349                         char* cpErr = NULL;
350                         chamberZ[chamberIndex] = strtod(argv[i+1], &cpErr);
351                         if (cpErr == NULL or *cpErr != '\0')
352                         {
353                                 HLTError("Cannot convert '%s' to a valid floating point number.",
354                                         argv[i+1]
355                                 );
356                                 return -EINVAL;
357                         }
358                         
359                         fCanLoadZ[chamberIndex] = false;  // Prevent loading from CDB.
360                         i++;
361                         continue;
362                 }
363                 
364                 if (strcmp(argv[i], "-warn_on_unexpected_block") == 0)
365                 {
366                         fWarnForUnexpecedBlock = true;
367                         continue;
368                 }
369
370                 HLTError("Unknown option '%s'.", argv[i]);
371                 return -EINVAL;
372         }
373         
374         try
375         {
376                 fTracker = new AliHLTMUONMansoTrackerFSM();
377         }
378         catch (const std::bad_alloc&)
379         {
380                 HLTError("Could not allocate more memory for the tracker component.");
381                 return -ENOMEM;
382         }
383         fTracker->SetCallback(this);
384         
385         // Set all the parameters that were found on the command line.
386         if (not fCanLoadZmiddle) AliHLTMUONCalculations::Zf(zmiddle);
387         if (not fCanLoadBL) AliHLTMUONCalculations::QBL(bfieldintegral);
388         if (not fCanLoadA[0]) fTracker->SetA7(roiA[0]);
389         if (not fCanLoadA[1]) fTracker->SetA8(roiA[1]);
390         if (not fCanLoadA[2]) fTracker->SetA9(roiA[2]);
391         if (not fCanLoadA[3]) fTracker->SetA10(roiA[3]);
392         if (not fCanLoadB[0]) fTracker->SetB7(roiB[0]);
393         if (not fCanLoadB[1]) fTracker->SetB8(roiB[1]);
394         if (not fCanLoadB[2]) fTracker->SetB9(roiB[2]);
395         if (not fCanLoadB[3]) fTracker->SetB10(roiB[3]);
396         if (not fCanLoadZ[0]) fTracker->SetZ7(chamberZ[0]);
397         if (not fCanLoadZ[1]) fTracker->SetZ8(chamberZ[1]);
398         if (not fCanLoadZ[2]) fTracker->SetZ9(chamberZ[2]);
399         if (not fCanLoadZ[3]) fTracker->SetZ10(chamberZ[3]);
400         if (not fCanLoadZ[4]) fTracker->SetZ11(chamberZ[4]);
401         if (not fCanLoadZ[5]) fTracker->SetZ13(chamberZ[5]);
402         
403         if (not DelaySetup())
404         {
405                 if (AtLeastOneCanLoadFlagsIsSet())
406                 {
407                         HLTInfo("Loading configuration parameters from CDB.");
408                         
409                         int result = ReadConfigFromCDB();
410                         if (result != 0)
411                         {
412                                 // Error messages already generated in ReadConfigFromCDB.
413                                 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
414                                 return result;
415                         }
416                 }
417                 else
418                 {
419                         // Print the debug messages here since ReadConfigFromCDB does not get called,
420                         // in-which the debug messages would have been printed.
421                         HLTDebug("Using the following configuration parameters:");
422                         HLTDebug("                    Middle of dipole Z coordinate = %f cm", AliHLTMUONCalculations::Zf());
423                         HLTDebug("                          Magnetic field integral = %f T.m", AliHLTMUONCalculations::QBL());
424                         HLTDebug("   Region of interest parameter 'A' for chamber 7 = %f",    fTracker->GetA7());
425                         HLTDebug("   Region of interest parameter 'B' for chamber 7 = %f cm", fTracker->GetB7());
426                         HLTDebug("   Region of interest parameter 'A' for chamber 8 = %f",    fTracker->GetA8());
427                         HLTDebug("   Region of interest parameter 'B' for chamber 8 = %f cm", fTracker->GetB8());
428                         HLTDebug("   Region of interest parameter 'A' for chamber 9 = %f",    fTracker->GetA9());
429                         HLTDebug("   Region of interest parameter 'B' for chamber 9 = %f cm", fTracker->GetB9());
430                         HLTDebug("  Region of interest parameter 'A' for chamber 10 = %f",    fTracker->GetA10());
431                         HLTDebug("  Region of interest parameter 'B' for chamber 10 = %f cm", fTracker->GetB10());
432                         HLTDebug("               Nominal Z coordinate for chamber 7 = %f cm", fTracker->GetZ7());
433                         HLTDebug("               Nominal Z coordinate for chamber 8 = %f cm", fTracker->GetZ8());
434                         HLTDebug("               Nominal Z coordinate for chamber 9 = %f cm", fTracker->GetZ9());
435                         HLTDebug("              Nominal Z coordinate for chamber 10 = %f cm", fTracker->GetZ10());
436                         HLTDebug("              Nominal Z coordinate for chamber 11 = %f cm", fTracker->GetZ11());
437                         HLTDebug("              Nominal Z coordinate for chamber 13 = %f cm", fTracker->GetZ13());
438                 }
439                 
440                 ResetCanLoadFlags();  // From this point read all parameters from CDB.
441         }
442         
443         const int initArraySize = 10;
444         // Allocate some initial memory for the reconstructed hit arrays.
445         try
446         {
447                 fRecHitBlock[0] = new AliRecHitBlockInfo[initArraySize*4];
448         }
449         catch (const std::bad_alloc&)
450         {
451                 HLTError("Could not allocate more memory for the reconstructed hit arrays.");
452                 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
453                 return -ENOMEM;
454         }
455         // Only set the arrays' size once we have successfully allocated the memory for the arrays.
456         fRecHitBlockArraySize = initArraySize;
457         // Now we need to set the pointers fRecHitBlock[i] {i>0} relative to fRecHitBlock[0].
458         for (Int_t i = 1; i < 4; i++)
459         {
460                 fRecHitBlock[i] = fRecHitBlock[i-1] + fRecHitBlockArraySize;
461         }
462         // And reset the number of records actually stored in the arrays.
463         for (Int_t i = 0; i < 4; i++)
464         {
465                 fRecHitBlockCount[i] = 0;
466         }
467         
468         return 0;
469 }
470
471
472 int AliHLTMUONMansoTrackerFSMComponent::Reconfigure(
473                 const char* cdbEntry, const char* componentId
474         )
475 {
476         /// Inherited from AliHLTComponent. This method will reload CDB configuration
477         /// entries for this component from the CDB.
478         /// \param cdbEntry If this is NULL or equals "HLT/ConfigMUON/MansoTrackerFSM"
479         ///     then new configuration parameters are loaded, otherwise nothing is done.
480         /// \param componentId  The name of the component in the current chain.
481         
482         bool givenConfigPath = strcmp(cdbEntry, AliHLTMUONConstants::MansoTrackerFSMCDBPath()) == 0;
483         
484         if (cdbEntry == NULL or givenConfigPath)
485         {
486                 HLTInfo("Reading new configuration entries from CDB for component '%s'.", componentId);
487                 ResetCanLoadFlags();  // Make sure to allow reading all values from CDB.
488                 int result = ReadConfigFromCDB();
489                 if (result != 0) return result;
490         }
491         
492         return 0;
493 }
494
495
496 int AliHLTMUONMansoTrackerFSMComponent::ReadPreprocessorValues(const char* modules)
497 {
498         /// Inherited from AliHLTComponent. 
499         /// Updates the configuration of this component if HLT or ALL has been
500         /// specified in the 'modules' list.
501
502         TString mods = modules;
503         if (mods.Contains("ALL"))
504         {
505                 return Reconfigure(NULL, GetComponentID());
506         }
507         if (mods.Contains("HLT"))
508         {
509                 return Reconfigure(AliHLTMUONConstants::MansoTrackerFSMCDBPath(), GetComponentID());
510         }
511         return 0;
512 }
513
514
515 int AliHLTMUONMansoTrackerFSMComponent::ReadConfigFromCDB()
516 {
517         /// Reads this component's configuration parameters from the CDB.
518         /// These include the middle of the dipole Z coordinate (zmiddle), the
519         /// integrated magnetic field of the dipole, Z coordinates of the chambers
520         /// and the region of interest parameters used during the tracking.
521         /// \param setZmiddle Indicates if the zmiddle parameter should be set
522         ///       (default true).
523         /// \param setBL Indicates if the integrated magnetic field parameter should
524         ///       be set (default true).
525         /// \return 0 if no errors occured and negative error code compatible with
526         ///       the HLT framework on errors.
527
528         const char* pathToEntry = AliHLTMUONConstants::MansoTrackerFSMCDBPath();
529         
530         TMap* map = NULL;
531         int result = FetchTMapFromCDB(pathToEntry, map);
532         if (result != 0) return result;
533         
534         Double_t value = 0;
535         if (fCanLoadZmiddle)
536         {
537                 result = GetFloatFromTMap(map, "zmiddle", value, pathToEntry, "dipole middle Z coordinate");
538                 if (result != 0) return result;
539                 AliHLTMUONCalculations::Zf(value);
540         }
541         
542         if (fCanLoadBL)
543         {
544                 result = GetFloatFromTMap(map, "bfieldintegral", value, pathToEntry, "integrated magnetic field");
545                 if (result != 0) return result;
546                 AliHLTMUONCalculations::QBL(value);
547         }
548         
549         if (fCanLoadA[0])
550         {
551                 result = GetFloatFromTMap(map, "roi_paramA_chamber7", value, pathToEntry, "chamber 7 region of interest 'A'");
552                 if (result != 0) return result;
553                 fTracker->SetA7(value);
554         }
555         if (fCanLoadA[1])
556         {
557                 result = GetFloatFromTMap(map, "roi_paramA_chamber8", value, pathToEntry, "chamber 8 region of interest 'A'");
558                 if (result != 0) return result;
559                 fTracker->SetA8(value);
560         }
561         if (fCanLoadA[2])
562         {
563                 result = GetFloatFromTMap(map, "roi_paramA_chamber9", value, pathToEntry, "chamber 9 region of interest 'A'");
564                 if (result != 0) return result;
565                 fTracker->SetA9(value);
566         }
567         if (fCanLoadA[3])
568         {
569                 result = GetFloatFromTMap(map, "roi_paramA_chamber10", value, pathToEntry, "chamber 10 region of interest 'A'");
570                 if (result != 0) return result;
571                 fTracker->SetA10(value);
572         }
573         
574         if (fCanLoadB[0])
575         {
576                 result = GetFloatFromTMap(map, "roi_paramB_chamber7", value, pathToEntry, "chamber 7 region of interest 'B'");
577                 if (result != 0) return result;
578                 fTracker->SetB7(value);
579         }
580         if (fCanLoadB[1])
581         {
582                 result = GetFloatFromTMap(map, "roi_paramB_chamber8", value, pathToEntry, "chamber 8 region of interest 'B'");
583                 if (result != 0) return result;
584                 fTracker->SetB8(value);
585         }
586         if (fCanLoadB[2])
587         {
588                 result = GetFloatFromTMap(map, "roi_paramB_chamber9", value, pathToEntry, "chamber 9 region of interest 'B'");
589                 if (result != 0) return result;
590                 fTracker->SetB9(value);
591         }
592         if (fCanLoadB[3])
593         {
594                 result = GetFloatFromTMap(map, "roi_paramB_chamber10", value, pathToEntry, "chamber 10 region of interest 'B'");
595                 if (result != 0) return result;
596                 fTracker->SetB10(value);
597         }
598         
599         if (fCanLoadZ[0])
600         {
601                 result = GetFloatFromTMap(map, "chamber7postion", value, pathToEntry, "nominal chamber 7 Z coordinate");
602                 if (result != 0) return result;
603                 fTracker->SetZ7(value);
604         }
605         if (fCanLoadZ[1])
606         {
607                 result = GetFloatFromTMap(map, "chamber8postion", value, pathToEntry, "nominal chamber 8 Z coordinate");
608                 if (result != 0) return result;
609                 fTracker->SetZ8(value);
610         }
611         if (fCanLoadZ[2])
612         {
613                 result = GetFloatFromTMap(map, "chamber9postion", value, pathToEntry, "nominal chamber 9 Z coordinate");
614                 if (result != 0) return result;
615                 fTracker->SetZ9(value);
616         }
617         if (fCanLoadZ[3])
618         {
619                 result = GetFloatFromTMap(map, "chamber10postion", value, pathToEntry, "nominal chamber 10 Z coordinate");
620                 if (result != 0) return result;
621                 fTracker->SetZ10(value);
622         }
623         if (fCanLoadZ[4])
624         {
625                 result = GetFloatFromTMap(map, "chamber11postion", value, pathToEntry, "nominal chamber 11 Z coordinate");
626                 if (result != 0) return result;
627                 fTracker->SetZ11(value);
628         }
629         if (fCanLoadZ[5])
630         {
631                 result = GetFloatFromTMap(map, "chamber13postion", value, pathToEntry, "nominal chamber 13 Z coordinate");
632                 if (result != 0) return result;
633                 fTracker->SetZ13(value);
634         }
635         
636         HLTDebug("Using the following configuration parameters:");
637         HLTDebug("                    Middle of dipole Z coordinate = %f cm", AliHLTMUONCalculations::Zf());
638         HLTDebug("                          Magnetic field integral = %f T.m", AliHLTMUONCalculations::QBL());
639         HLTDebug("   Region of interest parameter 'A' for chamber 7 = %f",    fTracker->GetA7());
640         HLTDebug("   Region of interest parameter 'B' for chamber 7 = %f cm", fTracker->GetB7());
641         HLTDebug("   Region of interest parameter 'A' for chamber 8 = %f",    fTracker->GetA8());
642         HLTDebug("   Region of interest parameter 'B' for chamber 8 = %f cm", fTracker->GetB8());
643         HLTDebug("   Region of interest parameter 'A' for chamber 9 = %f",    fTracker->GetA9());
644         HLTDebug("   Region of interest parameter 'B' for chamber 9 = %f cm", fTracker->GetB9());
645         HLTDebug("  Region of interest parameter 'A' for chamber 10 = %f",    fTracker->GetA10());
646         HLTDebug("  Region of interest parameter 'B' for chamber 10 = %f cm", fTracker->GetB10());
647         HLTDebug("               Nominal Z coordinate for chamber 7 = %f cm", fTracker->GetZ7());
648         HLTDebug("               Nominal Z coordinate for chamber 8 = %f cm", fTracker->GetZ8());
649         HLTDebug("               Nominal Z coordinate for chamber 9 = %f cm", fTracker->GetZ9());
650         HLTDebug("              Nominal Z coordinate for chamber 10 = %f cm", fTracker->GetZ10());
651         HLTDebug("              Nominal Z coordinate for chamber 11 = %f cm", fTracker->GetZ11());
652         HLTDebug("              Nominal Z coordinate for chamber 13 = %f cm", fTracker->GetZ13());
653         
654         return 0;
655 }
656
657
658 int AliHLTMUONMansoTrackerFSMComponent::DoDeinit()
659 {
660         ///
661         /// Inherited from AliHLTComponent. Performs a cleanup of the component.
662         ///
663         
664         HLTInfo("Deinitialising dHLT manso tracker FSM component.");
665         FreeMemory();
666         return 0;
667 }
668
669
670 int AliHLTMUONMansoTrackerFSMComponent::DoEvent(
671                 const AliHLTComponentEventData& evtData,
672                 const AliHLTComponentBlockData* blocks,
673                 AliHLTComponentTriggerData& trigData,
674                 AliHLTUInt8_t* outputPtr,
675                 AliHLTUInt32_t& size,
676                 AliHLTComponentBlockDataList& outputBlocks
677         )
678 {
679         ///
680         /// Inherited from AliHLTProcessor. Processes the new event data.
681         ///
682         
683         // Initialise the configuration parameters from CDB if we were
684         // requested to initialise only when the first event was received.
685         if (DelaySetup())
686         {
687                 // Load the configuration paramters from CDB if they have not
688                 // been given on the command line.
689                 if (AtLeastOneCanLoadFlagsIsSet())
690                 {
691                         HLTInfo("Loading configuration parameters from CDB.");
692                         int result = ReadConfigFromCDB();
693                         if (result != 0) return result;
694                 }
695                 
696                 DoneDelayedSetup();
697                 ResetCanLoadFlags();  // From this point read all parameters from CDB.
698         }
699         
700         Reset();
701         AliHLTUInt32_t specification = 0;  // Contains the output data block spec bits.
702         
703         // Resize the rec hit arrays if we possibly will need more space.
704         // To guarantee that they will not overflow we need to make sure each
705         // array is at least as big as the number of input data blocks.
706         if (fRecHitBlockArraySize < evtData.fBlockCnt)
707         {
708                 // Release the old memory block and allocate more memory.
709                 if (fRecHitBlock[0] != NULL)
710                 {
711                         delete [] fRecHitBlock[0];
712                 }
713                 
714                 // Reset the number of records actually stored in the arrays.
715                 for (Int_t i = 0; i < 4; i++)
716                 {
717                         fRecHitBlockCount[i] = 0;
718                 }
719                 
720                 try
721                 {
722                         fRecHitBlock[0] = new AliRecHitBlockInfo[evtData.fBlockCnt*4];
723                 }
724                 catch (const std::bad_alloc&)
725                 {
726                         HLTError("Could not allocate more memory for the reconstructed hit arrays.");
727                         // Ok so now we need to clear all the pointers because we actually
728                         // deleted the memory.
729                         fRecHitBlockArraySize = 0;
730                         for (Int_t i = 0; i < 4; i++)
731                         {
732                                 fRecHitBlock[i] = NULL;
733                         }
734                         if (DumpDataOnError()) DumpEvent(evtData, blocks, trigData, outputPtr, size, outputBlocks);
735                         return -ENOMEM;
736                 }
737                 // Only set the arrays' size once we have successfully allocated the memory for the arrays.
738                 fRecHitBlockArraySize = evtData.fBlockCnt;
739                 // Now we need to set the pointers fRecHitBlock[i] {i>0} relative to fRecHitBlock[0].
740                 for (Int_t i = 1; i < 4; i++)
741                 {
742                         fRecHitBlock[i] = fRecHitBlock[i-1] + fRecHitBlockArraySize;
743                 }
744         }
745         
746         AliHLTMUONMansoTracksBlockWriter block(outputPtr, size);
747         fBlock = &block;
748         
749         if (not block.InitCommonHeader())
750         {
751                 Logging(kHLTLogError,
752                         "AliHLTMUONMansoTrackerFSMComponent::DoEvent",
753                         "Buffer overflow",
754                         "The buffer is only %d bytes in size. We need a minimum of %d bytes.",
755                         size, sizeof(AliHLTMUONMansoTracksBlockWriter::HeaderType)
756                 );
757                 if (DumpDataOnError()) DumpEvent(evtData, blocks, trigData, outputPtr, size, outputBlocks);
758                 size = 0; // Important to tell framework that nothing was generated.
759                 return -ENOBUFS;
760         }
761
762         // Loop over all input blocks in the event and add the ones that contain
763         // reconstructed hits into the hit buffers. The blocks containing trigger
764         // records are ignored for now and will be processed later.
765         for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
766         {
767                 HLTDebug("Handling block: %u, with fDataType = '%s', fPtr = %p and fSize = %u bytes.",
768                         n, DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fPtr, blocks[n].fSize
769                 );
770                 
771                 if (blocks[n].fDataType == AliHLTMUONConstants::RecHitsBlockDataType())
772                 {
773                         specification |= blocks[n].fSpecification;
774                         
775                         AliHLTMUONRecHitsBlockReader inblock(blocks[n].fPtr, blocks[n].fSize);
776                         if (not BlockStructureOk(inblock))
777                         {
778                                 if (DumpDataOnError()) DumpEvent(evtData, blocks, trigData, outputPtr, size, outputBlocks);
779                                 continue;
780                         }
781                         
782                         if (inblock.Nentries() != 0)
783                                 AddRecHits(blocks[n].fSpecification, inblock.GetArray(), inblock.Nentries());
784                         else
785                         {
786                                 Logging(kHLTLogDebug,
787                                         "AliHLTMUONMansoTrackerFSMComponent::DoEvent",
788                                         "Block empty",
789                                         "Received a reconstructed hits data block which contains no entries."
790                                 );
791                         }
792                 }
793                 else if (blocks[n].fDataType != AliHLTMUONConstants::TriggerRecordsBlockDataType())
794                 {
795                         // Log a message indicating that we got a data block that we
796                         // do not know how to handle.
797                         if (fWarnForUnexpecedBlock)
798                                 HLTWarning("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
799                                         DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification
800                                 );
801                         else
802                                 HLTDebug("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
803                                         DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification
804                                 );
805                 }
806         }
807   
808         // Again loop over all input blocks in the event, but this time look for
809         // the trigger record blocks and process these.
810         for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
811         {
812                 if (blocks[n].fDataType != AliHLTMUONConstants::TriggerRecordsBlockDataType())
813                         continue;
814                 
815                 AliHLTMUONTriggerRecordsBlockReader inblock(blocks[n].fPtr, blocks[n].fSize);
816                 if (not BlockStructureOk(inblock))
817                 {
818                         if (DumpDataOnError()) DumpEvent(evtData, blocks, trigData, outputPtr, size, outputBlocks);
819                         continue;
820                 }
821                 
822                 DebugTrace("Processing a trigger block with "
823                         << inblock.Nentries() << " entries."
824                 );
825                 
826                 specification |= blocks[n].fSpecification;
827                 
828                 for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
829                 {
830                         fTracker->FindTrack(inblock[i]);
831                         
832                         // Reset the tracker so that we do not double count tracks.
833                         fTracker->Reset();
834                 }
835         }
836         
837         AliHLTComponentBlockData bd;
838         FillBlockData(bd);
839         bd.fPtr = outputPtr;
840         bd.fOffset = 0;
841         bd.fSize = block.BytesUsed();
842         bd.fDataType = AliHLTMUONConstants::MansoTracksBlockDataType();
843         bd.fSpecification = specification;
844         outputBlocks.push_back(bd);
845         size = block.BytesUsed();
846
847         return 0;
848 }
849
850
851 void AliHLTMUONMansoTrackerFSMComponent::Reset()
852 {
853         ///
854         /// Reset the track count and reconstructed hit data block arrays.
855         ///
856         
857         DebugTrace("Resetting AliHLTMUONMansoTrackerFSMComponent.");
858
859         //fTracker->Reset();  // Not necessary here because it is done after every FindTrack call.
860         fTrackCount = 0;
861         fBlock = NULL;  // Do not delete. Already done implicitly at the end of DoEvent.
862         for (int i = 0; i < 4; i++)
863         {
864                 fRecHitBlockCount[i] = 0;
865         }
866 }
867
868
869 void AliHLTMUONMansoTrackerFSMComponent::FreeMemory()
870 {
871         /// Deletes any objects and arrays allocated by this component and releases
872         /// the memory used. This is called as a helper routine by the init and deinit
873         /// methods. If some or all of the object pointers are already NULL then
874         /// nothing is done for those. This method guarantees that all the relevant
875         /// pointers will be NULL after returning from this method.
876
877         if (fTracker != NULL)
878         {
879                 delete fTracker;
880                 fTracker = NULL;
881         }
882         
883         // Remember that only fRecHitBlock[0] stores the pointer to the allocated memory.
884         // The other pointers are just reletive to this.
885         if (fRecHitBlock[0] != NULL)
886                 delete [] fRecHitBlock[0];
887         
888         fRecHitBlockArraySize = 0;
889         for (Int_t i = 0; i < 4; i++)
890         {
891                 fRecHitBlockCount[i] = 0;
892                 fRecHitBlock[i] = NULL;
893         }
894 }
895
896
897 void AliHLTMUONMansoTrackerFSMComponent::AddRecHits(
898                 AliHLTUInt32_t specification,
899                 const AliHLTMUONRecHitStruct* recHits,
900                 AliHLTUInt32_t count
901         )
902 {
903         ///
904         /// Adds a new reconstructed hit data block to the internal list of blocks
905         /// for the tracker to process.
906         /// These lists will later be used when the tracker requests them through
907         /// the callback method 'RequestClusters'.
908         ///
909         
910         DebugTrace("AliHLTMUONMansoTrackerFSMComponent::AddRecHits called with specification = 0x"
911                  << std::hex << specification << std::dec << " and count = "
912                  << count << " rec hits."
913         );
914         
915         AliHLTUInt8_t chamberMap[20] = {
916                 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10
917         };
918         
919         // Identify the chamber the rec hits came from using the specifications field.
920         bool gotDataFromDDL[22];
921         AliHLTMUONUtils::UnpackSpecBits(specification, gotDataFromDDL);
922                 
923         AliHLTInt8_t chamber = -1;
924         for (int i = 0; i < 20; i++)
925         {
926                 if (not gotDataFromDDL[i]) continue;
927                 if (7 <= chamberMap[i] and chamberMap[i] <= 10)
928                 {
929                         if (chamber != -1 and chamber != chamberMap[i])
930                         {
931                                 Logging(kHLTLogError,
932                                         "AliHLTMUONMansoTrackerFSMComponent::AddRecHits",
933                                         "Invalid block",
934                                         "Received a data block with data from multiple chambers."
935                                           " This component cannot handle such a case."
936                                 );
937                                 return;
938                         }
939                         else
940                                 chamber = chamberMap[i];
941                 }
942                 else
943                 {
944                         Logging(kHLTLogError,
945                                 "AliHLTMUONMansoTrackerFSMComponent::AddRecHits",
946                                 "Invalid chamber",
947                                 "Received a data block with data from chamber %d"
948                                   " which is outside the expected range: [7..10].",
949                                 chamberMap[i]
950                         );
951                         return;
952                 }
953         }
954         
955         // Make sure we got one chamber number.
956         if (chamber < 7 or 10 < chamber)
957         {
958                 Logging(kHLTLogError,
959                         "AliHLTMUONMansoTrackerFSMComponent::AddRecHits",
960                         "Invalid block",
961                         "Received a reconstructed hit data block with a null specification."
962                          " Cannot know which chamber the data comes from."
963                 );
964                 return;
965         }
966         
967         DebugTrace("Added " << count << " reconstructed hits from chamber "
968                 << (int)chamber << " to the internal arrays."
969         );
970         
971         assert( fRecHitBlockCount[chamber-7] < fRecHitBlockArraySize );
972         AliRecHitBlockInfo info(count, recHits);
973         fRecHitBlock[chamber-7][fRecHitBlockCount[chamber-7]] = info;
974         fRecHitBlockCount[chamber-7]++;
975 }
976
977
978 void AliHLTMUONMansoTrackerFSMComponent::ResetCanLoadFlags()
979 {
980         /// Resets all the fCanLoad* flags to true. This enables loading of all
981         /// those CDB entries in the method ReadConfigFromCDB.
982         
983         fCanLoadZmiddle = true;
984         fCanLoadBL = true;
985         for (int i = 0; i < 4; i++)
986         {
987                 fCanLoadA[i] = true;
988                 fCanLoadB[i] = true;
989         }
990         for (int i = 0; i < 6; i++)
991         {
992                 fCanLoadZ[i] = true;
993         }
994 }
995
996
997 bool AliHLTMUONMansoTrackerFSMComponent::AtLeastOneCanLoadFlagsIsSet() const
998 {
999         /// Returns true if at least one fCanLoad* flag was true and false otherwise.
1000
1001         if (fCanLoadZmiddle or fCanLoadBL) return true;
1002         for (int i = 0; i < 4; i++)
1003         {
1004                 if (fCanLoadA[i]) return true;
1005                 if (fCanLoadB[i]) return true;
1006         }
1007         for (int i = 0; i < 6; i++)
1008         {
1009                 if (fCanLoadZ[i]) return true;
1010         }
1011         return false;
1012 }
1013
1014
1015 void AliHLTMUONMansoTrackerFSMComponent::RequestClusters(
1016                 AliHLTMUONMansoTrackerFSM* tracker,
1017                 AliHLTFloat32_t left, AliHLTFloat32_t right,
1018                 AliHLTFloat32_t bottom, AliHLTFloat32_t top,
1019                 AliHLTMUONChamberName chamber, const void* tag
1020         )
1021 {
1022         ///
1023         /// Inherited from AliHLTMUONMansoTrackerFSMCallback.
1024         /// This is the call back method used by the tracker algorithm to request
1025         /// clusters on a certain chamber.
1026         ///
1027
1028         DebugTrace("AliHLTMUONMansoTracker::RequestClusters(chamber = " << chamber << ")");
1029         void* ctag = const_cast<void*>(tag);
1030         int chNo = -1;
1031         AliHLTUInt32_t recHitsCount = 0;
1032         AliRecHitBlockInfo* recHitsBlock = NULL;
1033         switch (chamber)
1034         {
1035         case kChamber7:
1036                 recHitsCount = fRecHitBlockCount[0];
1037                 recHitsBlock = fRecHitBlock[0];
1038                 chNo = 7;
1039                 break;
1040
1041         case kChamber8:
1042                 recHitsCount = fRecHitBlockCount[1];
1043                 recHitsBlock = fRecHitBlock[1];
1044                 chNo = 8;
1045                 break;
1046
1047         case kChamber9:
1048                 recHitsCount = fRecHitBlockCount[2];
1049                 recHitsBlock = fRecHitBlock[2];
1050                 chNo = 9;
1051                 break;
1052
1053         case kChamber10:
1054                 recHitsCount = fRecHitBlockCount[3];
1055                 recHitsBlock = fRecHitBlock[3];
1056                 chNo = 10;
1057                 break;
1058
1059         default: return;
1060         }
1061         
1062         DebugTrace("Returning requested hits for chamber " << chNo << ":");
1063         for (AliHLTUInt32_t i = 0; i < recHitsCount; i++)
1064         for (AliHLTUInt32_t j = 0; j < recHitsBlock[i].Count(); j++)
1065         {
1066                 const AliHLTMUONRecHitStruct* hit = &(recHitsBlock[i].Data()[j]);
1067                 if (left < hit->fX and hit->fX < right and bottom < hit->fY and hit->fY < top)
1068                         tracker->ReturnClusters(ctag, hit, 1);
1069         }
1070         DebugTrace("Done returning hits from chamber " << chNo << ".");
1071         tracker->EndOfClusters(ctag);
1072 }
1073
1074
1075 void AliHLTMUONMansoTrackerFSMComponent::EndOfClusterRequests(
1076                 AliHLTMUONMansoTrackerFSM* /*tracker*/
1077         )
1078 {
1079         ///
1080         /// Inherited from AliHLTMUONMansoTrackerFSMCallback.
1081         /// Nothing special to do here.
1082         ///
1083         
1084         DebugTrace("End of cluster requests.");
1085 }
1086
1087
1088 void AliHLTMUONMansoTrackerFSMComponent::FoundTrack(AliHLTMUONMansoTrackerFSM* tracker)
1089 {
1090         ///
1091         /// Inherited from AliHLTMUONMansoTrackerFSMCallback.
1092         /// This is the call back method used by the tracker algorithm to declare
1093         /// that a new track has been found.
1094         ///
1095         
1096         DebugTrace("AliHLTMUONMansoTrackerFSMComponent::FoundTrack()");
1097         
1098         AliHLTMUONMansoTracksBlockWriter* block =
1099                 reinterpret_cast<AliHLTMUONMansoTracksBlockWriter*>(fBlock);
1100         
1101         AliHLTMUONMansoTrackStruct* track = block->AddEntry();
1102         if (track == NULL)
1103         {
1104                 Logging(kHLTLogError,
1105                         "AliHLTMUONMansoTrackerFSMComponent::FoundTrack",
1106                         "Buffer overflow",
1107                         "We have overflowed the output buffer for Manso track data."
1108                           " The output buffer size is only %d bytes.",
1109                         block->BufferSize()
1110                 );
1111                 return;
1112         }
1113  
1114         fTrackCount++;
1115         tracker->FillTrackData(*track);
1116         DebugTrace("\tTrack data = " << *track);
1117 }
1118
1119
1120 void AliHLTMUONMansoTrackerFSMComponent::NoTrackFound(AliHLTMUONMansoTrackerFSM* /*tracker*/)
1121 {
1122         ///
1123         /// Inherited from AliHLTMUONMansoTrackerFSMCallback.
1124         /// Nothing special to do here.
1125         ///
1126         
1127         DebugTrace("No track found.");
1128 }
1129