]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/MUON/OnlineAnalysis/AliHLTMUONMansoTrackerFSMComponent.cxx
ALIROOT-5433 Transition to CDHv3 in HLT
[u/mrichter/AliRoot.git] / HLT / MUON / OnlineAnalysis / AliHLTMUONMansoTrackerFSMComponent.cxx
CommitLineData
b92524d0 1/**************************************************************************
bc5cb6d6 2 * This file is property of and copyright by the ALICE HLT Project *
b92524d0 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 *
bc5cb6d6 14 * about the suitability of this software for any purpose. It is *
b92524d0 15 * provided "as is" without express or implied warranty. *
16 **************************************************************************/
17
1d8ae082 18// $Id$
b92524d0 19
6253e09b 20///
21/// @file AliHLTMUONMansoTrackerFSMComponent.cxx
22/// @author Artur Szostak <artursz@iafrica.com>,
23/// Indranil Das <indra.das@saha.ac.in>
4e22efc4 24/// @date 18 Sep 2007
6253e09b 25/// @brief Implementation of AliHLTMUONMansoTrackerFSMComponent class.
26///
b92524d0 27
28#include "AliHLTMUONMansoTrackerFSMComponent.h"
29#include "AliHLTMUONConstants.h"
2b7af22a 30#include "AliHLTMUONCalculations.h"
b92524d0 31#include "AliHLTMUONUtils.h"
32#include "AliHLTMUONMansoTrackerFSM.h"
33#include "AliHLTMUONDataBlockReader.h"
34#include "AliHLTMUONDataBlockWriter.h"
35#include <cstdlib>
d42549e3 36#include <cstring>
b92524d0 37#include <cerrno>
5bf92d6f 38#include <new>
b92524d0 39
b92524d0 40ClassImp(AliHLTMUONMansoTrackerFSMComponent);
41
42
43AliHLTMUONMansoTrackerFSMComponent::AliHLTMUONMansoTrackerFSMComponent() :
154cba94 44 AliHLTMUONProcessor(),
b92524d0 45 AliHLTMUONMansoTrackerFSMCallback(),
46 fTracker(NULL),
47 fTrackCount(0),
d42549e3 48 fBlock(NULL),
5bf92d6f 49 fRecHitBlockArraySize(0),
2b7af22a 50 fWarnForUnexpecedBlock(false),
2b7af22a 51 fCanLoadZmiddle(true),
52 fCanLoadBL(true)
b92524d0 53{
6253e09b 54 ///
55 /// Default constructor.
56 ///
5bf92d6f 57
2b7af22a 58 for (int i = 0; i < 4; i++)
5bf92d6f 59 {
60 fRecHitBlockCount[i] = 0;
61 fRecHitBlock[i] = NULL;
62 }
2b7af22a 63
64 ResetCanLoadFlags();
b92524d0 65}
66
67
68AliHLTMUONMansoTrackerFSMComponent::~AliHLTMUONMansoTrackerFSMComponent()
69{
6253e09b 70 ///
71 /// Default destructor.
72 ///
73
a6b16447 74 // Should never have the following 2 pointers non-NULL since DoDeinit
75 // should have been called before, but handle this case anyway.
76 if (fTracker != NULL) delete fTracker;
77
78 // Remember that only fRecHitBlock[0] stores the pointer to the allocated
79 // memory. The other pointers are just reletive to this.
80 if (fRecHitBlock[0] != NULL) delete [] fRecHitBlock[0];
b92524d0 81}
82
83
84const char* AliHLTMUONMansoTrackerFSMComponent::GetComponentID()
85{
6253e09b 86 ///
87 /// Inherited from AliHLTComponent. Returns the component ID.
88 ///
89
b92524d0 90 return AliHLTMUONConstants::MansoTrackerFSMId();
91}
92
93
94void AliHLTMUONMansoTrackerFSMComponent::GetInputDataTypes(
ffb64d3e 95 AliHLTComponentDataTypeList& list
b92524d0 96 )
97{
6253e09b 98 ///
99 /// Inherited from AliHLTProcessor. Returns the list of expected input data types.
100 ///
101
b92524d0 102 assert( list.empty() );
103 list.push_back( AliHLTMUONConstants::TriggerRecordsBlockDataType() );
104 list.push_back( AliHLTMUONConstants::RecHitsBlockDataType() );
105}
106
107
108AliHLTComponentDataType AliHLTMUONMansoTrackerFSMComponent::GetOutputDataType()
109{
6253e09b 110 ///
111 /// Inherited from AliHLTComponent. Returns the output data type.
112 ///
113
4d76a068 114 return kAliHLTMultipleDataType;
115}
116
117
118int AliHLTMUONMansoTrackerFSMComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& list)
119{
120 /// Inherited from AliHLTComponent. Returns the output data types.
121
122 assert( list.empty() );
123 list.push_back( AliHLTMUONConstants::MansoTracksBlockDataType() );
124 list.push_back( AliHLTMUONConstants::MansoCandidatesBlockDataType() );
125 return list.size();
b92524d0 126}
127
128
129void AliHLTMUONMansoTrackerFSMComponent::GetOutputDataSize(
130 unsigned long& constBase, double& inputMultiplier
131 )
132{
6253e09b 133 ///
134 /// Inherited from AliHLTComponent. Returns an estimate of the expected output data size.
135 ///
136
979076f8 137 constBase = sizeof(AliHLTMUONMansoTracksBlockStruct) + 1024*1024;
b92524d0 138 inputMultiplier = 1;
139}
140
141
142AliHLTComponent* AliHLTMUONMansoTrackerFSMComponent::Spawn()
143{
6253e09b 144 ///
145 /// Inherited from AliHLTComponent. Creates a new object instance.
146 ///
147
b92524d0 148 return new AliHLTMUONMansoTrackerFSMComponent;
149}
150
151
152int AliHLTMUONMansoTrackerFSMComponent::DoInit(int argc, const char** argv)
153{
6253e09b 154 ///
155 /// Inherited from AliHLTComponent.
156 /// Parses the command line parameters and initialises the component.
157 ///
158
6ec6a7c1 159 HLTInfo("Initialising dHLT manso tracker FSM component.");
160
ffb64d3e 161 // Inherit the parents functionality.
162 int result = AliHLTMUONProcessor::DoInit(argc, argv);
163 if (result != 0) return result;
164
a6b16447 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 FreeMemory();
168
d42549e3 169 fWarnForUnexpecedBlock = false;
bc5cb6d6 170 bool makeCandidates = false;
2b7af22a 171 ResetCanLoadFlags();
2b7af22a 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};
d42549e3 177
178 for (int i = 0; i < argc; i++)
179 {
ffb64d3e 180 if (ArgumentAlreadyHandled(i, argv[i])) continue;
181
2b7af22a 182 if (strcmp( argv[i], "-zmiddle" ) == 0)
183 {
184 if (not fCanLoadZmiddle)
185 {
186 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 if ( argc <= i+1 )
192 {
193 HLTError("The Z coordinate for the middle of the dipole was not specified." );
2b7af22a 194 return -EINVAL;
195 }
196
197 char* cpErr = NULL;
198 zmiddle = strtod(argv[i+1], &cpErr);
199 if (cpErr == NULL or *cpErr != '\0')
200 {
201 HLTError("Cannot convert '%s' to a valid floating point number.",
202 argv[i+1]
203 );
2b7af22a 204 return -EINVAL;
205 }
206
207 fCanLoadZmiddle = false; // Prevent loading from CDB.
208 i++;
209 continue;
210 }
211
212 if (strcmp( argv[i], "-bfieldintegral" ) == 0)
213 {
214 if (not fCanLoadBL)
215 {
216 HLTWarning("The magnetic field integral was already specified."
217 " Will replace previous value given by -bfieldintegral."
218 );
219 }
220
221 if ( argc <= i+1 )
222 {
223 HLTError("The magnetic field integral was not specified." );
2b7af22a 224 return -EINVAL;
225 }
226
227 char* cpErr = NULL;
228 bfieldintegral = strtod(argv[i+1], &cpErr);
229 if (cpErr == NULL or *cpErr != '\0')
230 {
231 HLTError("Cannot convert '%s' to a valid floating point number.",
232 argv[i+1]
233 );
2b7af22a 234 return -EINVAL;
235 }
236
237 fCanLoadBL = false; // Prevent loading from CDB.
238 i++;
239 continue;
240 }
241
242 if (strcmp(argv[i], "-a7") == 0 or strcmp(argv[i], "-a8") == 0 or
243 strcmp(argv[i], "-a9") == 0 or strcmp(argv[i], "-a10") == 0
244 )
245 {
246 int chamber = 7; int chamberIndex = 0;
247 switch (argv[i][2])
248 {
249 case '7': chamber = 7; chamberIndex = 0; break;
250 case '8': chamber = 8; chamberIndex = 1; break;
251 case '9': chamber = 9; chamberIndex = 2; break;
252 case '1': chamber = 10; chamberIndex = 3; break;
253 }
254
255 if (not fCanLoadA[chamberIndex])
256 {
257 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 if ( argc <= i+1 )
264 {
265 HLTError("The region of interest parameter was not specified." );
2b7af22a 266 return -EINVAL;
267 }
268
269 char* cpErr = NULL;
270 roiA[chamberIndex] = strtod(argv[i+1], &cpErr);
271 if (cpErr == NULL or *cpErr != '\0')
272 {
273 HLTError("Cannot convert '%s' to a valid floating point number.",
274 argv[i+1]
275 );
2b7af22a 276 return -EINVAL;
277 }
278
279 fCanLoadA[chamberIndex] = false; // Prevent loading from CDB.
280 i++;
281 continue;
282 }
283
284 if (strcmp(argv[i], "-b7") == 0 or strcmp(argv[i], "-b8") == 0 or
285 strcmp(argv[i], "-b9") == 0 or strcmp(argv[i], "-b10") == 0
286 )
287 {
288 int chamber = 7; int chamberIndex = 0;
289 switch (argv[i][2])
290 {
291 case '7': chamber = 7; chamberIndex = 0; break;
292 case '8': chamber = 8; chamberIndex = 1; break;
293 case '9': chamber = 9; chamberIndex = 2; break;
294 case '1': chamber = 10; chamberIndex = 3; break;
295 }
296
297 if (not fCanLoadB[chamberIndex])
298 {
299 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 if ( argc <= i+1 )
306 {
307 HLTError("The region of interest parameter was not specified." );
2b7af22a 308 return -EINVAL;
309 }
310
311 char* cpErr = NULL;
312 roiB[chamberIndex] = strtod(argv[i+1], &cpErr);
313 if (cpErr == NULL or *cpErr != '\0')
314 {
315 HLTError("Cannot convert '%s' to a valid floating point number.",
316 argv[i+1]
317 );
2b7af22a 318 return -EINVAL;
319 }
320
321 fCanLoadB[chamberIndex] = false; // Prevent loading from CDB.
322 i++;
323 continue;
324 }
325
326 if (strcmp(argv[i], "-z7") == 0 or strcmp(argv[i], "-z8") == 0 or
327 strcmp(argv[i], "-z9") == 0 or strcmp(argv[i], "-z10") == 0 or
328 strcmp(argv[i], "-z11") == 0 or strcmp(argv[i], "-z13") == 0
329 )
330 {
331 int chamber = 7; int chamberIndex = 0;
332 switch (argv[i][2])
333 {
334 case '7': chamber = 7; chamberIndex = 0; break;
335 case '8': chamber = 8; chamberIndex = 1; break;
336 case '9': chamber = 9; chamberIndex = 2; break;
337 case '1':
338 switch (argv[i][3])
339 {
340 case '0': chamber = 10; chamberIndex = 3; break;
341 case '1': chamber = 11; chamberIndex = 4; break;
342 case '3': chamber = 13; chamberIndex = 5; break;
343 }
344 break;
345 }
346
347 if (not fCanLoadZ[chamberIndex])
348 {
349 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 if ( argc <= i+1 )
356 {
357 HLTError("The region of interest parameter was not specified." );
2b7af22a 358 return -EINVAL;
359 }
360
361 char* cpErr = NULL;
362 chamberZ[chamberIndex] = strtod(argv[i+1], &cpErr);
363 if (cpErr == NULL or *cpErr != '\0')
364 {
365 HLTError("Cannot convert '%s' to a valid floating point number.",
366 argv[i+1]
367 );
2b7af22a 368 return -EINVAL;
369 }
370
371 fCanLoadZ[chamberIndex] = false; // Prevent loading from CDB.
372 i++;
373 continue;
374 }
375
d42549e3 376 if (strcmp(argv[i], "-warn_on_unexpected_block") == 0)
47415aa9 377 {
d42549e3 378 fWarnForUnexpecedBlock = true;
47415aa9 379 continue;
380 }
bc5cb6d6 381
382 if (strcmp(argv[i], "-makecandidates") == 0)
383 {
384 makeCandidates = true;
385 continue;
386 }
387
47415aa9 388 HLTError("Unknown option '%s'.", argv[i]);
a6b16447 389 return -EINVAL;
d42549e3 390 }
391
ffb64d3e 392 try
2b7af22a 393 {
ffb64d3e 394 fTracker = new AliHLTMUONMansoTrackerFSM();
395 }
396 catch (const std::bad_alloc&)
397 {
398 HLTError("Could not allocate more memory for the tracker component.");
399 return -ENOMEM;
2b7af22a 400 }
ffb64d3e 401 fTracker->SetCallback(this);
bc5cb6d6 402 fTracker->MakeCandidates(makeCandidates);
2b7af22a 403
404 // Set all the parameters that were found on the command line.
405 if (not fCanLoadZmiddle) AliHLTMUONCalculations::Zf(zmiddle);
406 if (not fCanLoadBL) AliHLTMUONCalculations::QBL(bfieldintegral);
407 if (not fCanLoadA[0]) fTracker->SetA7(roiA[0]);
408 if (not fCanLoadA[1]) fTracker->SetA8(roiA[1]);
409 if (not fCanLoadA[2]) fTracker->SetA9(roiA[2]);
410 if (not fCanLoadA[3]) fTracker->SetA10(roiA[3]);
411 if (not fCanLoadB[0]) fTracker->SetB7(roiB[0]);
412 if (not fCanLoadB[1]) fTracker->SetB8(roiB[1]);
413 if (not fCanLoadB[2]) fTracker->SetB9(roiB[2]);
414 if (not fCanLoadB[3]) fTracker->SetB10(roiB[3]);
415 if (not fCanLoadZ[0]) fTracker->SetZ7(chamberZ[0]);
416 if (not fCanLoadZ[1]) fTracker->SetZ8(chamberZ[1]);
417 if (not fCanLoadZ[2]) fTracker->SetZ9(chamberZ[2]);
418 if (not fCanLoadZ[3]) fTracker->SetZ10(chamberZ[3]);
419 if (not fCanLoadZ[4]) fTracker->SetZ11(chamberZ[4]);
420 if (not fCanLoadZ[5]) fTracker->SetZ13(chamberZ[5]);
421
ffb64d3e 422 if (not DelaySetup())
2b7af22a 423 {
424 if (AtLeastOneCanLoadFlagsIsSet())
425 {
426 HLTInfo("Loading configuration parameters from CDB.");
427
4e22efc4 428 result = ReadConfigFromCDB();
2b7af22a 429 if (result != 0)
430 {
431 // Error messages already generated in ReadConfigFromCDB.
432 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
433 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 ResetCanLoadFlags(); // From this point read all parameters from CDB.
460 }
461
5bf92d6f 462 const int initArraySize = 10;
a6b16447 463 // Allocate some initial memory for the reconstructed hit arrays.
5bf92d6f 464 try
465 {
466 fRecHitBlock[0] = new AliRecHitBlockInfo[initArraySize*4];
467 }
468 catch (const std::bad_alloc&)
469 {
470 HLTError("Could not allocate more memory for the reconstructed hit arrays.");
a6b16447 471 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
5bf92d6f 472 return -ENOMEM;
473 }
474 // Only set the arrays' size once we have successfully allocated the memory for the arrays.
475 fRecHitBlockArraySize = initArraySize;
476 // Now we need to set the pointers fRecHitBlock[i] {i>0} relative to fRecHitBlock[0].
477 for (Int_t i = 1; i < 4; i++)
478 {
479 fRecHitBlock[i] = fRecHitBlock[i-1] + fRecHitBlockArraySize;
480 }
481 // And reset the number of records actually stored in the arrays.
482 for (Int_t i = 0; i < 4; i++)
483 {
484 fRecHitBlockCount[i] = 0;
485 }
486
b92524d0 487 return 0;
488}
489
490
2b7af22a 491int 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
ad9d297e 501 TString path = cdbEntry;
502 bool givenConfigPath = (path == AliHLTMUONConstants::MansoTrackerFSMCDBPath());
2b7af22a 503
504 if (cdbEntry == NULL or givenConfigPath)
505 {
506 HLTInfo("Reading new configuration entries from CDB for component '%s'.", componentId);
507 ResetCanLoadFlags(); // Make sure to allow reading all values from CDB.
508 int result = ReadConfigFromCDB();
509 if (result != 0) return result;
510 }
511
512 return 0;
513}
514
515
516int 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 TString mods = modules;
523 if (mods.Contains("ALL"))
524 {
525 return Reconfigure(NULL, GetComponentID());
526 }
527 if (mods.Contains("HLT"))
528 {
529 return Reconfigure(AliHLTMUONConstants::MansoTrackerFSMCDBPath(), GetComponentID());
530 }
531 return 0;
532}
533
534
535int 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 const char* pathToEntry = AliHLTMUONConstants::MansoTrackerFSMCDBPath();
549
550 TMap* map = NULL;
551 int result = FetchTMapFromCDB(pathToEntry, map);
552 if (result != 0) return result;
553
554 Double_t value = 0;
555 if (fCanLoadZmiddle)
556 {
557 result = GetFloatFromTMap(map, "zmiddle", value, pathToEntry, "dipole middle Z coordinate");
558 if (result != 0) return result;
559 AliHLTMUONCalculations::Zf(value);
560 }
561
562 if (fCanLoadBL)
563 {
bc5cb6d6 564 Double_t bfieldintegral;
565 result = FetchFieldIntegral(bfieldintegral);
566 if (result == 0)
567 {
568 AliHLTMUONCalculations::QBL(bfieldintegral);
569 }
570 else
571 {
572 HLTWarning("Failed to load the magnetic field integral from GRP information.");
573 result = GetFloatFromTMap(map, "bfieldintegral", value, pathToEntry, "integrated magnetic field");
574 if (result != 0) return result;
575 HLTWarning(Form("Using deprecated magnetic field integral value of %f T.m.", value));
576 AliHLTMUONCalculations::QBL(value);
577 }
2b7af22a 578 }
579
580 if (fCanLoadA[0])
581 {
582 result = GetFloatFromTMap(map, "roi_paramA_chamber7", value, pathToEntry, "chamber 7 region of interest 'A'");
583 if (result != 0) return result;
584 fTracker->SetA7(value);
585 }
586 if (fCanLoadA[1])
587 {
588 result = GetFloatFromTMap(map, "roi_paramA_chamber8", value, pathToEntry, "chamber 8 region of interest 'A'");
589 if (result != 0) return result;
590 fTracker->SetA8(value);
591 }
592 if (fCanLoadA[2])
593 {
594 result = GetFloatFromTMap(map, "roi_paramA_chamber9", value, pathToEntry, "chamber 9 region of interest 'A'");
595 if (result != 0) return result;
596 fTracker->SetA9(value);
597 }
598 if (fCanLoadA[3])
599 {
600 result = GetFloatFromTMap(map, "roi_paramA_chamber10", value, pathToEntry, "chamber 10 region of interest 'A'");
601 if (result != 0) return result;
602 fTracker->SetA10(value);
603 }
604
605 if (fCanLoadB[0])
606 {
607 result = GetFloatFromTMap(map, "roi_paramB_chamber7", value, pathToEntry, "chamber 7 region of interest 'B'");
608 if (result != 0) return result;
609 fTracker->SetB7(value);
610 }
611 if (fCanLoadB[1])
612 {
613 result = GetFloatFromTMap(map, "roi_paramB_chamber8", value, pathToEntry, "chamber 8 region of interest 'B'");
614 if (result != 0) return result;
615 fTracker->SetB8(value);
616 }
617 if (fCanLoadB[2])
618 {
619 result = GetFloatFromTMap(map, "roi_paramB_chamber9", value, pathToEntry, "chamber 9 region of interest 'B'");
620 if (result != 0) return result;
621 fTracker->SetB9(value);
622 }
623 if (fCanLoadB[3])
624 {
625 result = GetFloatFromTMap(map, "roi_paramB_chamber10", value, pathToEntry, "chamber 10 region of interest 'B'");
626 if (result != 0) return result;
627 fTracker->SetB10(value);
628 }
629
630 if (fCanLoadZ[0])
631 {
632 result = GetFloatFromTMap(map, "chamber7postion", value, pathToEntry, "nominal chamber 7 Z coordinate");
633 if (result != 0) return result;
634 fTracker->SetZ7(value);
635 }
636 if (fCanLoadZ[1])
637 {
638 result = GetFloatFromTMap(map, "chamber8postion", value, pathToEntry, "nominal chamber 8 Z coordinate");
639 if (result != 0) return result;
640 fTracker->SetZ8(value);
641 }
642 if (fCanLoadZ[2])
643 {
644 result = GetFloatFromTMap(map, "chamber9postion", value, pathToEntry, "nominal chamber 9 Z coordinate");
645 if (result != 0) return result;
646 fTracker->SetZ9(value);
647 }
648 if (fCanLoadZ[3])
649 {
650 result = GetFloatFromTMap(map, "chamber10postion", value, pathToEntry, "nominal chamber 10 Z coordinate");
651 if (result != 0) return result;
652 fTracker->SetZ10(value);
653 }
654 if (fCanLoadZ[4])
655 {
656 result = GetFloatFromTMap(map, "chamber11postion", value, pathToEntry, "nominal chamber 11 Z coordinate");
657 if (result != 0) return result;
658 fTracker->SetZ11(value);
659 }
660 if (fCanLoadZ[5])
661 {
662 result = GetFloatFromTMap(map, "chamber13postion", value, pathToEntry, "nominal chamber 13 Z coordinate");
663 if (result != 0) return result;
664 fTracker->SetZ13(value);
665 }
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 return 0;
686}
687
688
b92524d0 689int AliHLTMUONMansoTrackerFSMComponent::DoDeinit()
690{
6253e09b 691 ///
692 /// Inherited from AliHLTComponent. Performs a cleanup of the component.
693 ///
694
6ec6a7c1 695 HLTInfo("Deinitialising dHLT manso tracker FSM component.");
a6b16447 696 FreeMemory();
b92524d0 697 return 0;
698}
699
700
701int AliHLTMUONMansoTrackerFSMComponent::DoEvent(
702 const AliHLTComponentEventData& evtData,
5def1693 703 const AliHLTComponentBlockData* blocks,
ffb64d3e 704 AliHLTComponentTriggerData& trigData,
5def1693 705 AliHLTUInt8_t* outputPtr,
b92524d0 706 AliHLTUInt32_t& size,
ffb64d3e 707 AliHLTComponentBlockDataList& outputBlocks
b92524d0 708 )
709{
6253e09b 710 ///
711 /// Inherited from AliHLTProcessor. Processes the new event data.
712 ///
713
2b7af22a 714 // Initialise the configuration parameters from CDB if we were
715 // requested to initialise only when the first event was received.
ffb64d3e 716 if (DelaySetup())
2b7af22a 717 {
718 // Load the configuration paramters from CDB if they have not
719 // been given on the command line.
720 if (AtLeastOneCanLoadFlagsIsSet())
721 {
722 HLTInfo("Loading configuration parameters from CDB.");
723 int result = ReadConfigFromCDB();
724 if (result != 0) return result;
725 }
726
ffb64d3e 727 DoneDelayedSetup();
2b7af22a 728 ResetCanLoadFlags(); // From this point read all parameters from CDB.
729 }
730
b92524d0 731 Reset();
732 AliHLTUInt32_t specification = 0; // Contains the output data block spec bits.
733
a6b16447 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.
5bf92d6f 737 if (fRecHitBlockArraySize < evtData.fBlockCnt)
738 {
739 // Release the old memory block and allocate more memory.
a6b16447 740 if (fRecHitBlock[0] != NULL)
741 {
742 delete [] fRecHitBlock[0];
743 }
744
5bf92d6f 745 // Reset the number of records actually stored in the arrays.
746 for (Int_t i = 0; i < 4; i++)
747 {
748 fRecHitBlockCount[i] = 0;
749 }
750
751 try
752 {
753 fRecHitBlock[0] = new AliRecHitBlockInfo[evtData.fBlockCnt*4];
754 }
755 catch (const std::bad_alloc&)
756 {
757 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 fRecHitBlockArraySize = 0;
761 for (Int_t i = 0; i < 4; i++)
762 {
763 fRecHitBlock[i] = NULL;
764 }
ffb64d3e 765 if (DumpDataOnError()) DumpEvent(evtData, blocks, trigData, outputPtr, size, outputBlocks);
5bf92d6f 766 return -ENOMEM;
767 }
768 // Only set the arrays' size once we have successfully allocated the memory for the arrays.
769 fRecHitBlockArraySize = evtData.fBlockCnt;
770 // Now we need to set the pointers fRecHitBlock[i] {i>0} relative to fRecHitBlock[0].
771 for (Int_t i = 1; i < 4; i++)
772 {
773 fRecHitBlock[i] = fRecHitBlock[i-1] + fRecHitBlockArraySize;
774 }
775 }
776
b92524d0 777 AliHLTMUONMansoTracksBlockWriter block(outputPtr, size);
778 fBlock = &block;
779
780 if (not block.InitCommonHeader())
781 {
782 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 size, sizeof(AliHLTMUONMansoTracksBlockWriter::HeaderType)
787 );
ffb64d3e 788 if (DumpDataOnError()) DumpEvent(evtData, blocks, trigData, outputPtr, size, outputBlocks);
b92524d0 789 size = 0; // Important to tell framework that nothing was generated.
5bf92d6f 790 return -ENOBUFS;
b92524d0 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 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
797 {
450e0b36 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
b92524d0 802 if (blocks[n].fDataType == AliHLTMUONConstants::RecHitsBlockDataType())
803 {
804 specification |= blocks[n].fSpecification;
805
3240b3ce 806 AliHLTMUONRecHitsBlockReader inblock(blocks[n].fPtr, blocks[n].fSize);
ffb64d3e 807 if (not BlockStructureOk(inblock))
808 {
809 if (DumpDataOnError()) DumpEvent(evtData, blocks, trigData, outputPtr, size, outputBlocks);
810 continue;
811 }
b92524d0 812
4a9f11d4 813 if (inblock.Nentries() != 0)
814 AddRecHits(blocks[n].fSpecification, inblock.GetArray(), inblock.Nentries());
815 else
816 {
d42549e3 817 Logging(kHLTLogDebug,
4a9f11d4 818 "AliHLTMUONMansoTrackerFSMComponent::DoEvent",
819 "Block empty",
820 "Received a reconstructed hits data block which contains no entries."
821 );
822 }
b92524d0 823 }
824 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.
d42549e3 828 if (fWarnForUnexpecedBlock)
450e0b36 829 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
d42549e3 831 );
4e22efc4 832#ifdef __DEBUG
d42549e3 833 else
450e0b36 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
d42549e3 836 );
4e22efc4 837#endif
b92524d0 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 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
844 {
845 if (blocks[n].fDataType != AliHLTMUONConstants::TriggerRecordsBlockDataType())
846 continue;
847
3240b3ce 848 AliHLTMUONTriggerRecordsBlockReader inblock(blocks[n].fPtr, blocks[n].fSize);
ffb64d3e 849 if (not BlockStructureOk(inblock))
850 {
851 if (DumpDataOnError()) DumpEvent(evtData, blocks, trigData, outputPtr, size, outputBlocks);
852 continue;
853 }
154cba94 854
b92524d0 855 DebugTrace("Processing a trigger block with "
856 << inblock.Nentries() << " entries."
857 );
858
859 specification |= blocks[n].fSpecification;
860
861 for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
862 {
863 fTracker->FindTrack(inblock[i]);
864
865 // Reset the tracker so that we do not double count tracks.
866 fTracker->Reset();
867 }
868 }
869
870 AliHLTComponentBlockData bd;
871 FillBlockData(bd);
872 bd.fPtr = outputPtr;
873 bd.fOffset = 0;
874 bd.fSize = block.BytesUsed();
875 bd.fDataType = AliHLTMUONConstants::MansoTracksBlockDataType();
876 bd.fSpecification = specification;
877 outputBlocks.push_back(bd);
bc5cb6d6 878 AliHLTUInt32_t totalSize = block.BytesUsed();
879
880 if (fTracker->MakeCandidates())
881 {
882 AliHLTMUONMansoCandidatesBlockWriter candidatesBlock(outputPtr+totalSize, size-totalSize);
883 if (not candidatesBlock.InitCommonHeader())
884 {
885 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 if (DumpDataOnError()) DumpEvent(evtData, blocks, trigData, outputPtr, size, outputBlocks);
890 size = 0; // Important to tell framework that nothing was generated.
891 return -ENOBUFS;
892 }
893
894 // Fill in the output block buffer.
895 candidatesBlock.SetNumberOfEntries(fTracker->TrackCandidatesCount());
896 for (AliHLTUInt32_t i = 0; i < fTracker->TrackCandidatesCount(); ++i)
897 {
898 candidatesBlock[i] = fTracker->TrackCandidates()[i];
899 }
900
901 fTracker->ZeroTrackCandidatesList();
902
903 AliHLTComponentBlockData bdc;
904 FillBlockData(bdc);
905 bdc.fPtr = outputPtr;
906 bdc.fOffset = totalSize;
907 bdc.fSize = candidatesBlock.BytesUsed();
908 bdc.fDataType = AliHLTMUONConstants::MansoCandidatesBlockDataType();
909 bdc.fSpecification = specification;
910 outputBlocks.push_back(bdc);
911 totalSize += candidatesBlock.BytesUsed();
912 }
913
914 size = totalSize;
b92524d0 915 return 0;
916}
917
918
919void AliHLTMUONMansoTrackerFSMComponent::Reset()
920{
6253e09b 921 ///
922 /// Reset the track count and reconstructed hit data block arrays.
923 ///
924
b92524d0 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 {
5bf92d6f 932 fRecHitBlockCount[i] = 0;
b92524d0 933 }
934}
935
936
a6b16447 937void 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
b92524d0 965void AliHLTMUONMansoTrackerFSMComponent::AddRecHits(
6253e09b 966 AliHLTUInt32_t specification,
b92524d0 967 const AliHLTMUONRecHitStruct* recHits,
968 AliHLTUInt32_t count
969 )
970{
6253e09b 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
b92524d0 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 {
31343bed 1012 if (fWarnForUnexpecedBlock)
1013 {
1014 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 chamberMap[i]
1020 );
1021 }
b92524d0 1022 return;
1023 }
1024 }
1025
1026 // Make sure we got one chamber number.
1027 if (chamber < 7 or 10 < chamber)
1028 {
1029 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 return;
1036 }
1037
1038 DebugTrace("Added " << count << " reconstructed hits from chamber "
d42549e3 1039 << (int)chamber << " to the internal arrays."
1040 );
b92524d0 1041
5bf92d6f 1042 assert( fRecHitBlockCount[chamber-7] < fRecHitBlockArraySize );
1043 AliRecHitBlockInfo info(count, recHits);
1044 fRecHitBlock[chamber-7][fRecHitBlockCount[chamber-7]] = info;
1045 fRecHitBlockCount[chamber-7]++;
b92524d0 1046}
1047
1048
2b7af22a 1049void 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 fCanLoadZmiddle = true;
1055 fCanLoadBL = true;
1056 for (int i = 0; i < 4; i++)
1057 {
1058 fCanLoadA[i] = true;
1059 fCanLoadB[i] = true;
1060 }
1061 for (int i = 0; i < 6; i++)
1062 {
1063 fCanLoadZ[i] = true;
1064 }
1065}
1066
1067
1068bool AliHLTMUONMansoTrackerFSMComponent::AtLeastOneCanLoadFlagsIsSet() const
1069{
1070 /// Returns true if at least one fCanLoad* flag was true and false otherwise.
1071
1072 if (fCanLoadZmiddle or fCanLoadBL) return true;
1073 for (int i = 0; i < 4; i++)
1074 {
1075 if (fCanLoadA[i]) return true;
1076 if (fCanLoadB[i]) return true;
1077 }
1078 for (int i = 0; i < 6; i++)
1079 {
1080 if (fCanLoadZ[i]) return true;
1081 }
1082 return false;
1083}
1084
1085
b92524d0 1086void AliHLTMUONMansoTrackerFSMComponent::RequestClusters(
1087 AliHLTMUONMansoTrackerFSM* tracker,
f1169efa 1088 AliHLTFloat32_t left, AliHLTFloat32_t right,
1089 AliHLTFloat32_t bottom, AliHLTFloat32_t top,
b92524d0 1090 AliHLTMUONChamberName chamber, const void* tag
1091 )
1092{
6253e09b 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
b92524d0 1099 DebugTrace("AliHLTMUONMansoTracker::RequestClusters(chamber = " << chamber << ")");
1100 void* ctag = const_cast<void*>(tag);
1101 int chNo = -1;
5bf92d6f 1102 AliHLTUInt32_t recHitsCount = 0;
1103 AliRecHitBlockInfo* recHitsBlock = NULL;
b92524d0 1104 switch (chamber)
1105 {
1106 case kChamber7:
5bf92d6f 1107 recHitsCount = fRecHitBlockCount[0];
1108 recHitsBlock = fRecHitBlock[0];
b92524d0 1109 chNo = 7;
1110 break;
1111
1112 case kChamber8:
5bf92d6f 1113 recHitsCount = fRecHitBlockCount[1];
1114 recHitsBlock = fRecHitBlock[1];
b92524d0 1115 chNo = 8;
1116 break;
1117
1118 case kChamber9:
5bf92d6f 1119 recHitsCount = fRecHitBlockCount[2];
1120 recHitsBlock = fRecHitBlock[2];
b92524d0 1121 chNo = 9;
1122 break;
1123
1124 case kChamber10:
5bf92d6f 1125 recHitsCount = fRecHitBlockCount[3];
1126 recHitsBlock = fRecHitBlock[3];
b92524d0 1127 chNo = 10;
1128 break;
1129
1130 default: return;
1131 }
1132
1133 DebugTrace("Returning requested hits for chamber " << chNo << ":");
5bf92d6f 1134 for (AliHLTUInt32_t i = 0; i < recHitsCount; i++)
1135 for (AliHLTUInt32_t j = 0; j < recHitsBlock[i].Count(); j++)
b92524d0 1136 {
5bf92d6f 1137 const AliHLTMUONRecHitStruct* hit = &(recHitsBlock[i].Data()[j]);
f1169efa 1138 if (left < hit->fX and hit->fX < right and bottom < hit->fY and hit->fY < top)
1139 tracker->ReturnClusters(ctag, hit, 1);
b92524d0 1140 }
1141 DebugTrace("Done returning hits from chamber " << chNo << ".");
1142 tracker->EndOfClusters(ctag);
1143}
1144
1145
1146void AliHLTMUONMansoTrackerFSMComponent::EndOfClusterRequests(
5def1693 1147 AliHLTMUONMansoTrackerFSM* /*tracker*/
b92524d0 1148 )
1149{
6253e09b 1150 ///
1151 /// Inherited from AliHLTMUONMansoTrackerFSMCallback.
1152 /// Nothing special to do here.
1153 ///
1154
b92524d0 1155 DebugTrace("End of cluster requests.");
1156}
1157
1158
1159void AliHLTMUONMansoTrackerFSMComponent::FoundTrack(AliHLTMUONMansoTrackerFSM* tracker)
1160{
6253e09b 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
b92524d0 1167 DebugTrace("AliHLTMUONMansoTrackerFSMComponent::FoundTrack()");
1168
1169 AliHLTMUONMansoTracksBlockWriter* block =
1170 reinterpret_cast<AliHLTMUONMansoTracksBlockWriter*>(fBlock);
1171
1f18ea3f 1172 AliHLTMUONMansoTrackStruct newTrack;
1173 tracker->FillTrackData(newTrack);
1174
f05f6212 1175 // The indicies of the duplicate tracks. If set to block->Nentries() then
1176 // this indicates the index is not used.
1177 AliHLTUInt32_t dup1 = block->Nentries();
1178 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.
1f18ea3f 1183 for (AliHLTUInt32_t i = 0; i < block->Nentries(); i++)
1184 {
1185 AliHLTMUONMansoTrackStruct& track = (*block)[i];
1186 bool hasNoDuplicates = true;
1187 for (AliHLTUInt32_t j = 0; j < 4; j++)
1188 {
1189 if (track.fHit[j] == AliHLTMUONConstants::NilRecHitStruct()) continue;
1190 if (newTrack.fHit[j] == AliHLTMUONConstants::NilRecHitStruct()) continue;
1191 if (track.fHit[j] == newTrack.fHit[j])
1192 {
1193 hasNoDuplicates = false;
1194 break;
1195 }
1196 }
1197 if (hasNoDuplicates) continue;
1198
f05f6212 1199 if (dup1 == block->Nentries())
1f18ea3f 1200 {
f05f6212 1201 dup1 = i;
1202 }
1203 else if (dup2 == block->Nentries())
1204 {
1205 dup2 = i;
1206 }
1207 else
1208 {
1209 HLTError("Found more than 2 tracks with duplicate hits. This is completely unexpected. Something is seriously wrong!");
1f18ea3f 1210 }
1f18ea3f 1211 }
1212
f05f6212 1213 if (dup1 != block->Nentries() and dup2 != block->Nentries())
b92524d0 1214 {
f05f6212 1215 // In this case we found 2 duplicate entries.
1216 // Figure out which one has the highest pT and keep only that one.
1217 AliHLTMUONMansoTrackStruct& track1 = (*block)[dup1];
1218 AliHLTMUONMansoTrackStruct& track2 = (*block)[dup2];
1219 double newPt = sqrt(newTrack.fPx * newTrack.fPx + newTrack.fPy * newTrack.fPy);
1220 double dupPt1 = sqrt(track1.fPx * track1.fPx + track1.fPy * track1.fPy);
1221 double dupPt2 = sqrt(track2.fPx * track2.fPx + track2.fPy * track2.fPy);
1222
1223 if (newPt >= dupPt1 and newPt >= dupPt2)
1224 {
1225 // The new track must replace both existing tracks.
1226 track1 = newTrack;
1227 track2 = (*block)[block->Nentries()-1];
1228 }
1229 else if (dupPt1 >= newPt and dupPt1 >= dupPt2)
1230 {
1231 // track1 has the highest pT so ignore the new track and delete track2.
1232 track2 = (*block)[block->Nentries()-1];
1233 }
1234 else
1235 {
1236 // In this case track2 must have the highest pT so ignore the new
1237 // track and delete track1.
1238 track1 = (*block)[block->Nentries()-1];
1239 }
1240
1241 // Decrement the number of entries because we deleted a track.
1242 assert(fTrackCount > 0);
1243 assert(block->Nentries() > 0);
1244 block->SetNumberOfEntries(block->Nentries()-1);
1245 fTrackCount--;
1246 }
1247 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 AliHLTMUONMansoTrackStruct& track1 = (*block)[dup1];
1253 double newPt = sqrt(newTrack.fPx * newTrack.fPx + newTrack.fPy * newTrack.fPy);
1254 double dupPt1 = sqrt(track1.fPx * track1.fPx + track1.fPy * track1.fPy);
1255 if (newPt >= dupPt1)
1256 {
1257 track1 = newTrack;
1258 }
1259 }
1260 else
1261 {
1262 // No track found with duplicate hits so we can add the new track as it is.
1263 AliHLTMUONMansoTrackStruct* track = block->AddEntry();
1264 if (track == NULL)
1265 {
1266 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 block->BufferSize()
1272 );
1273 return;
1274 }
1275
1276 fTrackCount++;
1277 *track = newTrack;
1278 DebugTrace("\tAdded new track: " << *track);
b92524d0 1279 }
b92524d0 1280}
1281
1282
5def1693 1283void AliHLTMUONMansoTrackerFSMComponent::NoTrackFound(AliHLTMUONMansoTrackerFSM* /*tracker*/)
b92524d0 1284{
6253e09b 1285 ///
1286 /// Inherited from AliHLTMUONMansoTrackerFSMCallback.
1287 /// Nothing special to do here.
1288 ///
1289
b92524d0 1290 DebugTrace("No track found.");
1291}
6253e09b 1292