]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/MUON/OnlineAnalysis/AliHLTMUONDecisionComponent.cxx
Improving documentation and macros.
[u/mrichter/AliRoot.git] / HLT / MUON / OnlineAnalysis / AliHLTMUONDecisionComponent.cxx
CommitLineData
c9537879 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 * *
8 * Permission to use, copy, modify and distribute this software and its *
9 * documentation strictly for non-commercial purposes is hereby granted *
10 * without fee, provided that the above copyright notice appears in all *
11 * copies and that both the copyright notice and this permission notice *
12 * appear in the supporting documentation. The authors make no claims *
13 * about the suitability of this software for any purpose. It is *
14 * provided "as is" without express or implied warranty. *
15 **************************************************************************/
16
1d8ae082 17// $Id: $
c9537879 18
19///
20/// @file AliHLTMUONDecisionComponent.cxx
21/// @author Artur Szostak <artursz@iafrica.com>
22/// @date 30 April 2008
23/// @brief Implementation of the decision component for dimuon HLT triggering.
24///
25// class documentation is in the header file.
26
27#include "AliHLTMUONDecisionComponent.h"
28#include "AliHLTMUONConstants.h"
29#include "AliHLTMUONUtils.h"
30#include "AliHLTMUONCalculations.h"
31#include "AliHLTMUONDataBlockReader.h"
32#include "AliHLTMUONDataBlockWriter.h"
33#include "AliCDBEntry.h"
34#include "AliCDBManager.h"
35#include "TObjString.h"
36#include "TString.h"
37#include <cstdlib>
38#include <cstring>
39#include <cerrno>
40#include <cmath>
41#include <new>
42
43
44// Helper type for memory allocation.
45typedef const AliHLTMUONMansoTrackStruct* AliHLTMUONMansoTrackStructP;
46
47
48ClassImp(AliHLTMUONDecisionComponent);
49
50
51AliHLTMUONDecisionComponent::AliHLTMUONDecisionComponent() :
154cba94 52 AliHLTMUONProcessor(),
c9537879 53 fMaxTracks(1),
54 fTrackCount(0),
55 fTracks(new AliHLTMUONMansoTrackStructP[fMaxTracks]),
56 fLowPtCut(1.), // 1 GeV/c cut
57 fHighPtCut(2.), // 2 GeV/c cut
58 fLowMassCut(2.5), // 2.7 GeV/c^2 cut
59 fHighMassCut(7.), // 8 GeV/c^2 cut
2b7af22a 60 fWarnForUnexpecedBlock(false),
2b7af22a 61 fLowPtCutSet(false),
62 fHighPtCutSet(false),
63 fLowMassCutSet(false),
cf7b241a 64 fHighMassCutSet(false),
65 fFillSinglesDetail(false),
66 fFillPairsDetail(false)
c9537879 67{
68 ///
69 /// Default constructor.
70 ///
71}
72
73
74AliHLTMUONDecisionComponent::~AliHLTMUONDecisionComponent()
75{
76 ///
77 /// Default destructor deletes the fTracks array.
78 ///
79
80 assert(fTracks != NULL);
81 delete [] fTracks;
82}
83
84
85const char* AliHLTMUONDecisionComponent::GetComponentID()
86{
87 ///
88 /// Inherited from AliHLTComponent. Returns the component ID.
89 ///
90
91 return AliHLTMUONConstants::DecisionComponentId();
92}
93
94
ffb64d3e 95void AliHLTMUONDecisionComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list)
c9537879 96{
97 ///
98 /// Inherited from AliHLTProcessor. Returns the list of expected input data types.
99 ///
100
101 assert( list.empty() );
102 list.push_back( AliHLTMUONConstants::MansoTracksBlockDataType() );
103}
104
105
106AliHLTComponentDataType AliHLTMUONDecisionComponent::GetOutputDataType()
107{
108 /// Inherited from AliHLTComponent. Returns kAliHLTMultipleDataType
109 /// refer to GetOutputDataTypes for all returned data types.
110
111 return kAliHLTMultipleDataType;
112}
113
114
115int AliHLTMUONDecisionComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& list)
116{
117 /// Inherited from AliHLTComponent. Returns the output data types.
118
119 assert( list.empty() );
120 list.push_back( AliHLTMUONConstants::SinglesDecisionBlockDataType() );
121 list.push_back( AliHLTMUONConstants::PairsDecisionBlockDataType() );
62a08849 122 return list.size();
c9537879 123}
124
125
126void AliHLTMUONDecisionComponent::GetOutputDataSize(
127 unsigned long& constBase, double& inputMultiplier
128 )
129{
130 ///
131 /// Inherited from AliHLTComponent. Returns an estimate of the expected output data size.
132 ///
133
134 constBase = sizeof(AliHLTMUONSinglesDecisionBlockStruct);
979076f8 135 constBase += sizeof(AliHLTMUONPairsDecisionBlockStruct) + 1024*1024;
210736fa 136 inputMultiplier = 100;
c9537879 137}
138
139
140AliHLTComponent* AliHLTMUONDecisionComponent::Spawn()
141{
142 ///
143 /// Inherited from AliHLTComponent. Creates a new object instance.
144 ///
145
146 return new AliHLTMUONDecisionComponent;
147}
148
149
150int AliHLTMUONDecisionComponent::DoInit(int argc, const char** argv)
151{
152 ///
153 /// Inherited from AliHLTComponent.
154 /// Parses the command line parameters and initialises the component.
155 ///
156
157 HLTInfo("Initialising dHLT trigger decision component.");
158
ffb64d3e 159 // Inherit the parents functionality.
160 int result = AliHLTMUONProcessor::DoInit(argc, argv);
161 if (result != 0) return result;
162
c9537879 163 fWarnForUnexpecedBlock = false;
2b7af22a 164 fLowPtCutSet = false;
165 fHighPtCutSet = false;
166 fLowMassCutSet = false;
167 fHighMassCutSet = false;
cf7b241a 168 fFillSinglesDetail = true;
169 fFillPairsDetail = true;
2b7af22a 170
c9537879 171 for (int i = 0; i < argc; i++)
172 {
ffb64d3e 173 if (ArgumentAlreadyHandled(i, argv[i])) continue;
174
c9537879 175 if (strcmp( argv[i], "-lowptcut" ) == 0)
176 {
2b7af22a 177 if (fLowPtCutSet)
ffc1a6f6 178 {
179 HLTWarning("Low pT cut parameter was already specified."
180 " Will replace previous value given by -lowptcut."
181 );
182 }
183
c9537879 184 if (argc <= i+1)
185 {
186 HLTError("The value for the low pT cut was not specified.");
187 return -EINVAL;
188 }
189
190 char* cpErr = NULL;
191 double num = strtod(argv[i+1], &cpErr);
192 if (cpErr == NULL or *cpErr != '\0')
193 {
194 HLTError("Cannot convert '%s' to a floating point number.", argv[i+1]);
195 return -EINVAL;
196 }
197 fLowPtCut = (AliHLTFloat32_t)num;
2b7af22a 198 fLowPtCutSet = true;
c9537879 199
200 i++;
201 continue;
202 }
203
204 if (strcmp( argv[i], "-highptcut" ) == 0)
205 {
2b7af22a 206 if (fHighPtCutSet)
ffc1a6f6 207 {
208 HLTWarning("High pT cut parameter was already specified."
209 " Will replace previous value given by -highptcut."
210 );
211 }
212
c9537879 213 if (argc <= i+1)
214 {
215 HLTError("The value for the high pT cut was not specified.");
216 return -EINVAL;
217 }
218
219 char* cpErr = NULL;
220 double num = strtod(argv[i+1], &cpErr);
221 if (cpErr == NULL or *cpErr != '\0')
222 {
223 HLTError("Cannot convert '%s' to a floating point number.", argv[i+1]);
224 return -EINVAL;
225 }
226 fHighPtCut = (AliHLTFloat32_t)num;
2b7af22a 227 fHighPtCutSet = true;
c9537879 228
229 i++;
230 continue;
231 }
232
233 if (strcmp( argv[i], "-lowmasscut" ) == 0)
234 {
2b7af22a 235 if (fLowMassCutSet)
ffc1a6f6 236 {
237 HLTWarning("Low invariant mass cut parameter was already specified."
238 " Will replace previous value given by -lowmasscut."
239 );
240 }
241
c9537879 242 if (argc <= i+1)
243 {
244 HLTError("The value for the low invariant mass cut was not specified.");
245 return -EINVAL;
246 }
247
248 char* cpErr = NULL;
249 double num = strtod(argv[i+1], &cpErr);
250 if (cpErr == NULL or *cpErr != '\0')
251 {
252 HLTError("Cannot convert '%s' to a floating point number.", argv[i+1]);
253 return -EINVAL;
254 }
255 fLowMassCut = (AliHLTFloat32_t)num;
2b7af22a 256 fLowMassCutSet = true;
c9537879 257
258 i++;
259 continue;
260 }
261
262 if (strcmp( argv[i], "-highmasscut" ) == 0)
263 {
2b7af22a 264 if (fHighMassCutSet)
ffc1a6f6 265 {
266 HLTWarning("High invariant mass cut parameter was already specified."
267 " Will replace previous value given by -highmasscut."
268 );
269 }
270
c9537879 271 if (argc <= i+1)
272 {
273 HLTError("The value for the high invariant mass cut was not specified.");
274 return -EINVAL;
275 }
276
277 char* cpErr = NULL;
278 double num = strtod(argv[i+1], &cpErr);
279 if (cpErr == NULL or *cpErr != '\0')
280 {
281 HLTError("Cannot convert '%s' to a floating point number.", argv[i+1]);
282 return -EINVAL;
283 }
284 fHighMassCut = (AliHLTFloat32_t)num;
2b7af22a 285 fHighMassCutSet = true;
c9537879 286
287 i++;
288 continue;
289 }
290
291 if (strcmp(argv[i], "-warn_on_unexpected_block") == 0)
292 {
293 fWarnForUnexpecedBlock = true;
294 continue;
295 }
cf7b241a 296
297 if (strcmp( argv[i], "-no_singles_detail" ) == 0)
298 {
299 fFillSinglesDetail = false;
300 continue;
301 }
302
303 if (strcmp( argv[i], "-no_pairs_detail" ) == 0)
304 {
305 fFillPairsDetail = false;
306 continue;
307 }
c9537879 308
309 HLTError("Unknown option '%s'.", argv[i]);
310 return -EINVAL;
311 }
312
ffb64d3e 313 if (not DelaySetup())
2b7af22a 314 {
315 // Read cut parameters from CDB if they were not specified on the command line.
316 if (not fLowPtCutSet or not fHighPtCutSet or not fLowMassCutSet or not fHighMassCutSet)
317 {
318 HLTInfo("Loading cut parameters from CDB.");
4e22efc4 319 result = ReadConfigFromCDB(
2b7af22a 320 not fLowPtCutSet, not fHighPtCutSet,
321 not fLowMassCutSet, not fHighMassCutSet
322 );
323 if (result != 0) return result;
324 }
325 else
326 {
327 // Print the debug messages here since ReadConfigFromCDB does not get called,
328 // in-which the debug messages would have been printed.
329 HLTDebug("Using the following cut parameters:");
330 HLTDebug(" Low pT cut = %f GeV/c", fLowPtCut);
331 HLTDebug(" High pT cut = %f GeV/c", fHighPtCut);
332 HLTDebug(" Low invariant mass cut = %f GeV/c^2", fLowMassCut);
333 HLTDebug(" High invariant mass cut = %f GeV/c^2", fHighMassCut);
334 }
335 }
c9537879 336
337 return 0;
338}
339
340
341int AliHLTMUONDecisionComponent::DoDeinit()
342{
343 ///
344 /// Inherited from AliHLTComponent. Performs a cleanup of the component.
345 ///
346
347 HLTInfo("Deinitialising dHLT trigger decision component.");
348 return 0;
349}
350
351
352int AliHLTMUONDecisionComponent::Reconfigure(const char* cdbEntry, const char* componentId)
353{
354 /// Inherited from AliHLTComponent. Reconfigures the component from CDB.
355
2b7af22a 356 /// Inherited from AliHLTComponent. This method will reload CDB configuration
357 /// entries for this component from the CDB.
358 /// \param cdbEntry If this is NULL or equals "HLT/ConfigMUON/DecisionComponent"
359 /// then new configuration parameters are loaded, otherwise nothing is done.
360 /// \param componentId The name of the component in the current chain.
361
362 bool givenConfigPath = strcmp(cdbEntry, AliHLTMUONConstants::DecisionComponentCDBPath()) == 0;
363
364 if (cdbEntry == NULL or givenConfigPath)
c9537879 365 {
2b7af22a 366 HLTInfo("Reading new configuration entries from CDB for component '%s'.", componentId);
367 int result = ReadConfigFromCDB();
368 if (result != 0) return result;
c9537879 369 }
2b7af22a 370
371 return 0;
372}
373
374
375int AliHLTMUONDecisionComponent::ReadPreprocessorValues(const char* modules)
376{
377 /// Inherited from AliHLTComponent.
378 /// Updates the configuration of this component if HLT or ALL has been
379 /// specified in the 'modules' list.
380
381 TString mods = modules;
382 if (mods.Contains("ALL"))
383 {
384 return Reconfigure(NULL, GetComponentID());
385 }
386 if (mods.Contains("HLT"))
387 {
388 return Reconfigure(AliHLTMUONConstants::DecisionComponentCDBPath(), GetComponentID());
389 }
390 return 0;
c9537879 391}
392
393
394int AliHLTMUONDecisionComponent::DoEvent(
395 const AliHLTComponentEventData& evtData,
396 const AliHLTComponentBlockData* blocks,
ffb64d3e 397 AliHLTComponentTriggerData& trigData,
c9537879 398 AliHLTUInt8_t* outputPtr,
399 AliHLTUInt32_t& size,
ffb64d3e 400 AliHLTComponentBlockDataList& outputBlocks
c9537879 401 )
402{
403 ///
404 /// Inherited from AliHLTProcessor. Processes the new event data.
405 ///
406
2b7af22a 407 // Initialise the cut parameters from CDB if we were requested to
408 // initialise only when the first event was received.
ffb64d3e 409 if (DelaySetup())
2b7af22a 410 {
411 // Load the cut paramters from CDB if they have not been given
412 // on the command line.
413 if (not fLowPtCutSet or not fHighPtCutSet or not fLowMassCutSet or not fHighMassCutSet)
414 {
415 HLTInfo("Loading cut parameters from CDB.");
416 int result = ReadConfigFromCDB(
417 not fLowPtCutSet, not fHighPtCutSet,
418 not fLowMassCutSet, not fHighMassCutSet
419 );
420 if (result != 0) return result;
421 }
422
ffb64d3e 423 DoneDelayedSetup();
2b7af22a 424 }
425
c9537879 426 AliHLTUInt32_t specification = 0; // Contains the output data block spec bits.
427
428 // Loop over all input blocks in the event with track data and add pointers
429 // to the tracks into the tracks array. These will be used later by the
430 // trigger algorithm to get to the individual tracks.
431 fTrackCount = 0; // reset number of tracks in array.
432 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
433 {
450e0b36 434 HLTDebug("Handling block: %u, with fDataType = '%s', fPtr = %p and fSize = %u bytes.",
435 n, DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fPtr, blocks[n].fSize
436 );
437
c9537879 438 if (blocks[n].fDataType == AliHLTMUONConstants::MansoTracksBlockDataType())
439 {
440 // Build up the specification which indicates what DDLs
441 // contributed to the output data.
442 specification |= blocks[n].fSpecification;
443
3240b3ce 444 AliHLTMUONMansoTracksBlockReader inblock(blocks[n].fPtr, blocks[n].fSize);
ffb64d3e 445 if (not BlockStructureOk(inblock))
446 {
447 if (DumpDataOnError()) DumpEvent(evtData, blocks, trigData, outputPtr, size, outputBlocks);
448 continue;
449 }
c9537879 450
451 for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
452 {
453 int result = AddTrack(&inblock[i]);
454 if (result != 0)
455 {
ffb64d3e 456 if (DumpDataOnError()) DumpEvent(evtData, blocks, trigData, outputPtr, size, outputBlocks);
c9537879 457 size = 0; // Important to tell framework that nothing was generated.
458 return result;
459 }
460 }
461 }
450e0b36 462 else
c9537879 463 {
464 // Log a message indicating that we got a data block that we
465 // do not know how to handle.
c9537879 466 if (fWarnForUnexpecedBlock)
450e0b36 467 HLTWarning("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
468 DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification
c9537879 469 );
4e22efc4 470#ifdef __DEBUG
c9537879 471 else
450e0b36 472 HLTDebug("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
473 DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification
c9537879 474 );
4e22efc4 475#endif
c9537879 476 }
477 }
478
479 // Now we can create our two new output data blocks for the single tracks
480 // and track pairs.
481 AliHLTMUONSinglesDecisionBlockWriter singlesBlock(outputPtr, size);
482
483 if (not singlesBlock.InitCommonHeader())
484 {
485 Logging(kHLTLogError,
486 "AliHLTMUONDecisionComponent::DoEvent",
487 "Buffer overflow",
488 "The buffer is only %d bytes in size. We need a minimum of"
489 " %d bytes for the singles output data block.",
490 size, sizeof(AliHLTMUONSinglesDecisionBlockWriter::HeaderType)
491 );
ffb64d3e 492 if (DumpDataOnError()) DumpEvent(evtData, blocks, trigData, outputPtr, size, outputBlocks);
c9537879 493 size = 0; // Important to tell framework that nothing was generated.
494 return -ENOBUFS;
495 }
cf7b241a 496
497 AliHLTUInt32_t numOfTracks = fTrackCount;
498 if (not fFillSinglesDetail) numOfTracks = 0;
499 if (not singlesBlock.SetNumberOfEntries(numOfTracks))
c9537879 500 {
501 AliHLTUInt32_t bytesneeded = sizeof(AliHLTMUONSinglesDecisionBlockWriter::HeaderType)
cf7b241a 502 + numOfTracks * sizeof(AliHLTMUONSinglesDecisionBlockWriter::ElementType);
c9537879 503 HLTError("The buffer is only %d bytes in size. We need a minimum of"
504 " %d bytes for the singles output data block.",
505 size, bytesneeded
506 );
ffb64d3e 507 if (DumpDataOnError()) DumpEvent(evtData, blocks, trigData, outputPtr, size, outputBlocks);
c9537879 508 size = 0; // Important to tell framework that nothing was generated.
509 return -ENOBUFS;
510 }
511
512 AliHLTMUONPairsDecisionBlockWriter pairsBlock(
513 outputPtr + singlesBlock.BytesUsed(),
514 size - singlesBlock.BytesUsed()
515 );
516
517 if (not pairsBlock.InitCommonHeader())
518 {
519 Logging(kHLTLogError,
520 "AliHLTMUONDecisionComponent::DoEvent",
521 "Buffer overflow",
522 "The buffer is only %d bytes in size. We need a minimum of"
523 " %d bytes for the pairs output data block.",
524 size,
525 sizeof(AliHLTMUONPairsDecisionBlockWriter::HeaderType) + singlesBlock.BytesUsed()
526 );
ffb64d3e 527 if (DumpDataOnError()) DumpEvent(evtData, blocks, trigData, outputPtr, size, outputBlocks);
c9537879 528 size = 0; // Important to tell framework that nothing was generated.
529 return -ENOBUFS;
530 }
cf7b241a 531
c9537879 532 AliHLTUInt32_t numOfPairs = fTrackCount * (fTrackCount-1) / 2;
cf7b241a 533 if (not fFillPairsDetail) numOfPairs = 0;
c9537879 534 if (not pairsBlock.SetNumberOfEntries(numOfPairs))
535 {
536 AliHLTUInt32_t bytesneeded = sizeof(AliHLTMUONPairsDecisionBlockWriter::HeaderType)
8a9e21f6 537 + numOfPairs * sizeof(AliHLTMUONPairsDecisionBlockWriter::ElementType)
c9537879 538 + singlesBlock.BytesUsed();
539 HLTError("The buffer is only %d bytes in size. We need a minimum of"
540 " %d bytes for the pairs output data block.",
541 size, bytesneeded
542 );
ffb64d3e 543 if (DumpDataOnError()) DumpEvent(evtData, blocks, trigData, outputPtr, size, outputBlocks);
c9537879 544 size = 0; // Important to tell framework that nothing was generated.
545 return -ENOBUFS;
546 }
547
548 ApplyTriggerAlgorithm(
549 singlesBlock.BlockHeader(),
550 singlesBlock.GetArray(),
551 pairsBlock.BlockHeader(),
552 pairsBlock.GetArray()
553 );
554
555 AliHLTComponentBlockData sbd;
556 FillBlockData(sbd);
557 sbd.fPtr = outputPtr;
558 sbd.fOffset = 0;
559 sbd.fSize = singlesBlock.BytesUsed();
560 sbd.fDataType = AliHLTMUONConstants::SinglesDecisionBlockDataType();
561 sbd.fSpecification = specification;
562 outputBlocks.push_back(sbd);
563 size = singlesBlock.BytesUsed();
564
565 AliHLTComponentBlockData pbd;
566 FillBlockData(pbd);
567 pbd.fPtr = outputPtr;
568 pbd.fOffset = singlesBlock.BytesUsed();
569 pbd.fSize = pairsBlock.BytesUsed();
570 pbd.fDataType = AliHLTMUONConstants::PairsDecisionBlockDataType();
571 pbd.fSpecification = specification;
572 outputBlocks.push_back(pbd);
573 size += pairsBlock.BytesUsed();
574
575 return 0;
576}
577
578
579int AliHLTMUONDecisionComponent::ReadConfigFromCDB(
c9537879 580 bool setLowPtCut, bool setHighPtCut,
581 bool setLowMassCut, bool setHighMassCut
582 )
583{
584 /// Reads the cut parameters from the CDB.
2b7af22a 585 /// \param setLowPtCut Indicates if the low pT cut should be set (default true).
586 /// \param setHighPtCut Indicates if the high pT cut should be set (default true).
587 /// \param setLowMassCut Indicates if the low invariant mass cut should be set (default true).
588 /// \param setHighMassCut Indicates if the high invariant mass cut should be set (default true).
589 /// \return 0 is returned on success and a non-zero value to indicate failure.
c9537879 590
591 assert(AliCDBManager::Instance() != NULL);
592
593 const char* pathToEntry = AliHLTMUONConstants::DecisionComponentCDBPath();
c9537879 594
ffc1a6f6 595 TMap* map = NULL;
596 int result = FetchTMapFromCDB(pathToEntry, map);
597 if (result != 0) return result;
c9537879 598
599 if (setLowPtCut)
600 {
ffc1a6f6 601 Double_t value = 0;
602 result = GetFloatFromTMap(map, "lowptcut", value, pathToEntry, "low pT cut");
603 if (result != 0) return result;
604 fLowPtCut = (AliHLTFloat32_t) value;
c9537879 605 }
606
607 if (setHighPtCut)
608 {
ffc1a6f6 609 Double_t value = 0;
610 result = GetFloatFromTMap(map, "highptcut", value, pathToEntry, "high pT cut");
611 if (result != 0) return result;
612 fHighPtCut = (AliHLTFloat32_t) value;
c9537879 613 }
614
615 if (setLowMassCut)
616 {
ffc1a6f6 617 Double_t value = 0;
618 result = GetFloatFromTMap(map, "lowmasscut", value, pathToEntry, "low invariant mass cut");
619 if (result != 0) return result;
620 fLowMassCut = (AliHLTFloat32_t) value;
c9537879 621 }
622
623 if (setHighMassCut)
624 {
ffc1a6f6 625 Double_t value = 0;
626 result = GetFloatFromTMap(map, "highmasscut", value, pathToEntry, "high invariant mass cut");
627 if (result != 0) return result;
628 fHighMassCut = (AliHLTFloat32_t) value;
c9537879 629 }
630
2b7af22a 631 HLTDebug("Using the following cut parameters:");
632 HLTDebug(" Low pT cut = %f GeV/c", fLowPtCut);
633 HLTDebug(" High pT cut = %f GeV/c", fHighPtCut);
634 HLTDebug(" Low invariant mass cut = %f GeV/c^2", fLowMassCut);
635 HLTDebug(" High invariant mass cut = %f GeV/c^2", fHighMassCut);
636
c9537879 637 return 0;
638}
639
640
641int AliHLTMUONDecisionComponent::AddTrack(const AliHLTMUONMansoTrackStruct* track)
642{
643 /// Adds a track to the internal track list for future reference in
644 /// ApplyTriggerAlgorithm when we actually apply the trigger algorithm.
645
646 assert(fTrackCount <= fMaxTracks);
647 assert(fTracks != NULL);
648
649 if (fTrackCount == fMaxTracks)
650 {
651 // Buffer full so we need to resize it.
652 const AliHLTMUONMansoTrackStruct** tmp = NULL;
653 try
654 {
655 tmp = new AliHLTMUONMansoTrackStructP[fMaxTracks+1];
656 }
657 catch (const std::bad_alloc&)
658 {
659 HLTError("Could not allocate more memory for the track array.");
660 return -ENOMEM;
661 }
662
663 // Copy over the exisiting data and then delete the old array.
664 memcpy(tmp, fTracks, sizeof(AliHLTMUONMansoTrackStructP)*fTrackCount);
665 delete [] fTracks;
666 fTracks = tmp;
667 fMaxTracks = fMaxTracks+1;
668 }
669
670 fTracks[fTrackCount] = track;
671 fTrackCount++;
672 return 0;
673}
674
675
cf7b241a 676int AliHLTMUONDecisionComponent::ApplyTriggerAlgorithm(
c9537879 677 AliHLTMUONSinglesDecisionBlockStruct& singlesHeader,
678 AliHLTMUONTrackDecisionStruct* singlesDecision,
679 AliHLTMUONPairsDecisionBlockStruct& pairsHeader,
680 AliHLTMUONPairDecisionStruct* pairsDecision
681 )
682{
683 /// This method applies the dHLT trigger decision algorithm to all the
684 /// tracks found in the input data.
cf7b241a 685 /// @return zero on success and -ENOMEM if out of memory.
c9537879 686
687 // Zero the trigger counters for single tracks.
688 singlesHeader.fNlowPt = 0;
689 singlesHeader.fNhighPt = 0;
690
691 // Zero the trigger counters for pairs.
692 pairsHeader.fNunlikeAnyPt = 0;
693 pairsHeader.fNunlikeLowPt = 0;
694 pairsHeader.fNunlikeHighPt = 0;
695 pairsHeader.fNlikeAnyPt = 0;
696 pairsHeader.fNlikeLowPt = 0;
697 pairsHeader.fNlikeHighPt = 0;
698 pairsHeader.fNmassAny = 0;
699 pairsHeader.fNmassLow = 0;
700 pairsHeader.fNmassHigh = 0;
cf7b241a 701
702 // Allocate a temporary memory buffer for the calculated pT values if
703 // we are not storing them to shared memory as part of the new block.
704 AliHLTFloat32_t* ptValues = NULL;
705 if (not fFillSinglesDetail)
706 {
707 try
708 {
709 ptValues = new AliHLTFloat32_t[fTrackCount];
710 }
711 catch(const std::bad_alloc&)
712 {
713 HLTError("Could not allocate memory buffer for pT values.");
714 return -ENOMEM;
715 }
716 }
c9537879 717
718 // For the single tracks we check if a track has pT larger than either
719 // the low or high pT cut. If it does then we increment the appropriate
720 // counters in the header.
721 for (AliHLTUInt32_t n = 0; n < fTrackCount; n++)
722 {
723 const AliHLTMUONMansoTrackStruct* track = fTracks[n];
c9537879 724
725 bool passedHighPtCut = false;
726 bool passedLowPtCut = false;
727
728 AliHLTFloat32_t pt = sqrt(track->fPx * track->fPx + track->fPy * track->fPy);
729
730 if (pt > fHighPtCut)
731 {
732 passedHighPtCut = true;
87e62032 733 singlesHeader.fNhighPt++;
c9537879 734 }
735 if (pt > fLowPtCut)
736 {
737 passedLowPtCut = true;
87e62032 738 singlesHeader.fNlowPt++;
c9537879 739 }
740
cf7b241a 741 if (fFillSinglesDetail)
742 {
743 AliHLTMUONTrackDecisionStruct& decision = singlesDecision[n];
744 decision.fTrackId = track->fId;
745 decision.fTriggerBits = AliHLTMUONUtils::PackTrackDecisionBits(
746 passedHighPtCut, passedLowPtCut
747 );
748 decision.fPt = pt;
749 }
750 else
751 {
752 ptValues[n] = pt;
753 }
c9537879 754 }
755
756 // Now we generate all the possible pairs of tracks and fill in the
757 // trigger information. This will consist of calculating the invariant
758 // mass for the pair, checking if it passes the low or high mass cut
759 // and incrementing the appropriate statistics.
760 AliHLTUInt32_t currentPair = 0;
761 for (AliHLTUInt32_t i = 0; i < fTrackCount; i++)
762 for (AliHLTUInt32_t j = i+1; j < fTrackCount; j++)
763 {
764 const AliHLTMUONMansoTrackStruct* tracki = fTracks[i];
765 const AliHLTMUONMansoTrackStruct* trackj = fTracks[j];
c9537879 766
767 AliHLTFloat32_t muMass = 0.1056583568; // muon mass in GeV/c^2
768
769 AliHLTFloat32_t mass = AliHLTMUONCalculations::ComputeMass(
770 muMass, tracki->fPx, tracki->fPy, tracki->fPz,
771 muMass, trackj->fPx, trackj->fPy, trackj->fPz
772 );
773
774 AliHLTMUONParticleSign signi, signj;
775 bool hitset[4];
776 AliHLTMUONUtils::UnpackMansoTrackFlags(tracki->fFlags, signi, hitset);
777 AliHLTMUONUtils::UnpackMansoTrackFlags(trackj->fFlags, signj, hitset);
778
779 AliHLTUInt8_t highPtCount = 0;
c9537879 780 AliHLTUInt8_t lowPtCount = 0;
cf7b241a 781 if (fFillSinglesDetail)
782 {
783 const AliHLTMUONTrackDecisionStruct& trackidecision = singlesDecision[i];
784 const AliHLTMUONTrackDecisionStruct& trackjdecision = singlesDecision[j];
785 if (trackidecision.fPt > fHighPtCut) highPtCount++;
786 if (trackjdecision.fPt > fHighPtCut) highPtCount++;
787 if (trackidecision.fPt > fLowPtCut) lowPtCount++;
788 if (trackjdecision.fPt > fLowPtCut) lowPtCount++;
789 }
790 else
791 {
792 if (ptValues[i] > fHighPtCut) highPtCount++;
793 if (ptValues[j] > fHighPtCut) highPtCount++;
794 if (ptValues[i] > fLowPtCut) lowPtCount++;
795 if (ptValues[j] > fLowPtCut) lowPtCount++;
796 }
c9537879 797
798 bool unlikeSign = (signi == kSignMinus and signj == kSignPlus) or
799 (signi == kSignPlus and signj == kSignMinus);
800
801 bool passedHighMassCut = false;
802 bool passedLowMassCut = false;
803 if (unlikeSign)
804 {
805 pairsHeader.fNunlikeAnyPt++;
806 if (lowPtCount == 2) pairsHeader.fNunlikeLowPt++;
807 if (highPtCount == 2) pairsHeader.fNunlikeHighPt++;
808
809 if (mass > fHighMassCut)
810 {
811 passedHighMassCut = true;
812 if (highPtCount == 2) pairsHeader.fNmassHigh++;
813 }
814 if (mass > fLowMassCut)
815 {
816 passedLowMassCut = true;
817 pairsHeader.fNmassAny++;
818 if (lowPtCount == 2) pairsHeader.fNmassLow++;
819 }
820 }
821 else
822 {
823 pairsHeader.fNlikeAnyPt++;
824 if (lowPtCount == 2) pairsHeader.fNlikeLowPt++;
825 if (highPtCount == 2) pairsHeader.fNlikeHighPt++;
826 }
827
cf7b241a 828 if (fFillPairsDetail)
829 {
830 AliHLTMUONPairDecisionStruct& decision = pairsDecision[currentPair];
831
832 decision.fTrackAId = tracki->fId;
833 decision.fTrackBId = trackj->fId;
834 decision.fTriggerBits = AliHLTMUONUtils::PackPairDecisionBits(
835 passedHighMassCut, passedLowMassCut, unlikeSign,
836 highPtCount, lowPtCount
837 );
838 decision.fInvMass = mass;
c9537879 839
cf7b241a 840 currentPair++;
841 }
c9537879 842 }
843
cf7b241a 844 assert( fFillPairsDetail == false or (fFillPairsDetail == true and currentPair == fTrackCount * (fTrackCount-1) / 2) );
845
846 if (not fFillSinglesDetail)
847 {
848 assert(ptValues != NULL);
849 delete [] ptValues;
850 }
851
852 return 0;
c9537879 853}
854