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