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