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