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