changes to run also on AOD MC
[u/mrichter/AliRoot.git] / HLT / MUON / OfflineInterface / AliHLTMUONRootifierComponent.cxx
CommitLineData
9acda34c 1/**************************************************************************
1d8ae082 2 * This file is property of and copyright by the ALICE HLT Project *
9acda34c 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 *
1d8ae082 13 * about the suitability of this software for any purpose. It is *
9acda34c 14 * provided "as is" without express or implied warranty. *
15 **************************************************************************/
16
1d8ae082 17// $Id$
9acda34c 18
cb35e21b 19///
20/// @file AliHLTMUONRootifierComponent.cxx
21/// @author Artur Szostak <artursz@iafrica.com>
450e0b36 22/// @date 29 Sep 2007
cb35e21b 23/// @brief Implementation of the AliHLTMUONRootifierComponent component.
24///
1d8ae082 25/// Implements a component to convert dHLT raw data into TObjects.
9acda34c 26
27#include "AliHLTMUONRootifierComponent.h"
450e0b36 28#include "AliHLTMUONEvent.h"
9acda34c 29#include "AliHLTMUONConstants.h"
30#include "AliHLTMUONUtils.h"
9acda34c 31#include "AliHLTMUONRecHit.h"
32#include "AliHLTMUONTriggerRecord.h"
33#include "AliHLTMUONMansoTrack.h"
450e0b36 34#include "AliHLTMUONDecision.h"
35#include "TClonesArray.h"
9acda34c 36#include <cassert>
37
9acda34c 38ClassImp(AliHLTMUONRootifierComponent);
39
40
41AliHLTMUONRootifierComponent::AliHLTMUONRootifierComponent() :
154cba94 42 AliHLTMUONProcessor(),
450e0b36 43 fWarnForUnexpecedBlock(false)
9acda34c 44{
6253e09b 45 ///
46 /// Default constructor.
47 ///
9acda34c 48}
49
50
51AliHLTMUONRootifierComponent::~AliHLTMUONRootifierComponent()
52{
6253e09b 53 ///
54 /// Default destructor.
55 ///
9acda34c 56}
57
58
ffb64d3e 59bool AliHLTMUONRootifierComponent::IgnoreArgument(const char* arg) const
60{
61 /// Return true if the argument is one of -cdbpath -run or -delaysetup
62 /// to prevent the parent class from parsing these arguments in DoInit.
63
558cf470 64 if (strcmp(arg, "-cdbpath") == 0 or strcmp(arg, "-run") == 0 or
65 strcmp(arg, "-delaysetup") == 0)
ffb64d3e 66 {
67 return true;
68 }
69 else
70 {
71 return false;
72 }
73}
74
75
450e0b36 76int AliHLTMUONRootifierComponent::DoInit(int argc, const char** argv)
9acda34c 77{
6253e09b 78 ///
79 /// Inherited from AliHLTComponent.
80 /// Parses the command line parameters and initialises the component.
81 ///
82
450e0b36 83 HLTInfo("Initialising dHLT rootifier component.");
ffb64d3e 84
85 // Inherit the parents functionality.
86 int result = AliHLTMUONProcessor::DoInit(argc, argv);
87 if (result != 0) return result;
450e0b36 88
89 fWarnForUnexpecedBlock = false;
90
91 for (int i = 0; i < argc; i++)
92 {
ffb64d3e 93 if (ArgumentAlreadyHandled(i, argv[i])) continue;
94
450e0b36 95 if (strcmp(argv[i], "-warn_on_unexpected_block") == 0)
96 {
97 fWarnForUnexpecedBlock = true;
98 continue;
99 }
100
101 HLTError("Unknown option '%s'.", argv[i]);
102 return -EINVAL;
103 }
104
9acda34c 105 return 0;
106}
107
108
109int AliHLTMUONRootifierComponent::DoDeinit()
110{
6253e09b 111 ///
112 /// Inherited from AliHLTComponent. Performs a cleanup of the component.
113 ///
114
450e0b36 115 HLTInfo("Deinitialising dHLT rootifier component.");
9acda34c 116 return 0;
117}
118
119
120const char* AliHLTMUONRootifierComponent::GetComponentID()
121{
6253e09b 122 ///
123 /// Inherited from AliHLTComponent. Returns the component ID.
124 ///
125
450e0b36 126 return AliHLTMUONConstants::RootifierComponentId();
9acda34c 127}
128
129
130AliHLTComponentDataType AliHLTMUONRootifierComponent::GetOutputDataType()
131{
bb14e9db 132 /// Inherited from AliHLTComponent. Returns kAliHLTMultipleDataType
133 /// refer to GetOutputDataTypes for all returned data types.
134
135 return kAliHLTMultipleDataType;
136}
137
138
139int AliHLTMUONRootifierComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList)
140{
141 /// Inherited from AliHLTComponent. Returns the output data types.
6253e09b 142
1d8ae082 143 tgtList.push_back(AliHLTMUONConstants::RootifiedEventDataType());
62a08849 144 return tgtList.size();
9acda34c 145}
146
147
ffb64d3e 148void AliHLTMUONRootifierComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list)
9acda34c 149{
6253e09b 150 ///
151 /// Inherited from AliHLTProcessor. Returns the list of expected input data types.
152 ///
153
9acda34c 154 list.push_back(kAliHLTAnyDataType);
155}
156
157
158void AliHLTMUONRootifierComponent::GetOutputDataSize(
159 unsigned long& constBase, double& inputMultiplier
160 )
161{
6253e09b 162 ///
163 /// Inherited from AliHLTComponent. Returns an estimate of the expected output data size.
164 ///
165
477135e2 166 constBase = 1024*1024;
167 inputMultiplier = 100;
9acda34c 168}
169
170
171AliHLTComponent* AliHLTMUONRootifierComponent::Spawn()
172{
6253e09b 173 ///
174 /// Inherited from AliHLTComponent. Creates a new object instance.
175 ///
176
9acda34c 177 return new AliHLTMUONRootifierComponent();
178}
179
180
181int AliHLTMUONRootifierComponent::DoEvent(
182 const AliHLTComponentEventData& evtData,
ffb64d3e 183 AliHLTComponentTriggerData& trigData
9acda34c 184 )
185{
6253e09b 186 ///
187 /// Inherited from AliHLTProcessor. Processes the new event data.
188 ///
189
83d66053 190 if (not IsDataEvent()) return 0;
191
9acda34c 192 AliHLTMUONEvent event(evtData.fEventID);
450e0b36 193 const AliHLTComponentBlockData* block = NULL;
649ab027 194 AliHLTUInt32_t specification = 0; // Contains the output data block spec bits.
9acda34c 195
196 // First process the blocks of reconstructed hits and trigger records.
197 for (int i = 0; i < GetNumberOfInputBlocks(); i++)
198 {
450e0b36 199 block = GetInputBlock(i);
9acda34c 200 assert( block != NULL );
450e0b36 201
202 HLTDebug("Handling block: %u, with fDataType = '%s', fPtr = %p and fSize = %u bytes.",
a62ffb4d 203 i, DataType2Text(block->fDataType).c_str(), block->fPtr, block->fSize
450e0b36 204 );
205
9acda34c 206 if (block->fDataType == AliHLTMUONConstants::RecHitsBlockDataType())
207 {
649ab027 208 specification |= block->fSpecification;
3240b3ce 209 AliHLTMUONRecHitsBlockReader inblock(block->fPtr, block->fSize);
ffb64d3e 210 if (not BlockStructureOk(inblock))
211 {
212 if (DumpDataOnError()) DumpEvent(evtData, trigData);
213 continue;
214 }
9acda34c 215
216 // Decode the source DDL from the specification bits.
217 Int_t sourceDDL = -1;
218 bool ddl[22];
219 AliHLTMUONUtils::UnpackSpecBits(block->fSpecification, ddl);
220 for (int k = 0; k < 22; k++)
221 {
222 if (ddl[k])
223 {
224 if (sourceDDL == -1)
225 {
226 sourceDDL = k+1;
227 }
228 else
229 {
230 HLTWarning("The input data block %d contains"
231 " data from multiple DDL sources.", i
232 );
233 }
234 }
235 }
236 if (sourceDDL > 20)
237 {
238 HLTWarning("The source DDL for input data block %d is %d."
239 " The expected range for the DDL is [1..20].",
240 i, sourceDDL
241 );
242 }
243
244 for (AliHLTUInt32_t n = 0; n < inblock.Nentries(); n++)
245 {
246 const AliHLTMUONRecHitStruct& h = inblock[n];
cdd0c63d 247 AliHLTUInt8_t chamber;
248 AliHLTUInt16_t detElemId;
249 AliHLTMUONUtils::UnpackRecHitFlags(h.fFlags, chamber, detElemId);
83d66053 250 event.Add(new AliHLTMUONRecHit(h.fX, h.fY, h.fZ, sourceDDL, detElemId));
9acda34c 251 }
252 }
253 else if (block->fDataType == AliHLTMUONConstants::TriggerRecordsBlockDataType())
254 {
649ab027 255 specification |= block->fSpecification;
3240b3ce 256 AliHLTMUONTriggerRecordsBlockReader inblock(block->fPtr, block->fSize);
ffb64d3e 257 if (not BlockStructureOk(inblock))
258 {
259 if (DumpDataOnError()) DumpEvent(evtData, trigData);
260 continue;
261 }
9acda34c 262
263 // Decode the source DDL from the specification bits.
264 Int_t sourceDDL = -1;
265 bool ddl[22];
266 AliHLTMUONUtils::UnpackSpecBits(block->fSpecification, ddl);
267 for (int k = 0; k < 22; k++)
268 {
269 if (ddl[k])
270 {
271 if (sourceDDL == -1)
272 {
273 sourceDDL = k+1;
274 }
275 else
276 {
277 HLTWarning("The input data block %d contains"
278 " data from multiple DDL sources.", i
279 );
280 }
281 }
282 }
bb14e9db 283 if (sourceDDL != -1 and (sourceDDL < 21 or sourceDDL > 22))
9acda34c 284 {
285 HLTWarning("The source DDL for input data block %d is %d."
286 " The expected range for the DDL is [21..22].",
287 i, sourceDDL
288 );
289 }
290
291 for (AliHLTUInt32_t n = 0; n < inblock.Nentries(); n++)
292 {
293 const AliHLTMUONTriggerRecordStruct& t = inblock[n];
294
295 AliHLTMUONParticleSign sign;
296 bool hitset[4];
297 AliHLTMUONUtils::UnpackTriggerRecordFlags(
298 t.fFlags, sign, hitset
299 );
300
301 AliHLTMUONTriggerRecord* tr = new AliHLTMUONTriggerRecord(
302 t.fId, sign, t.fPx, t.fPy, t.fPz, sourceDDL
303 );
304 for (int k = 0; k < 4; k++)
305 tr->SetHit(k+11, t.fHit[k].fX, t.fHit[k].fY, t.fHit[k].fZ);
306 event.Add(tr);
307 }
308 }
309 else
310 {
450e0b36 311 if (block->fDataType != AliHLTMUONConstants::MansoTracksBlockDataType() and
312 block->fDataType != AliHLTMUONConstants::SinglesDecisionBlockDataType() and
313 block->fDataType != AliHLTMUONConstants::PairsDecisionBlockDataType()
314 )
315 {
316 // Log a message indicating that we got a data block that we
317 // do not know how to handle.
318 if (fWarnForUnexpecedBlock)
319 HLTWarning("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
320 DataType2Text(block->fDataType).c_str(), block->fSpecification
321 );
4e22efc4 322#ifdef __DEBUG
450e0b36 323 else
324 HLTDebug("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
325 DataType2Text(block->fDataType).c_str(), block->fSpecification
326 );
4e22efc4 327#endif
450e0b36 328 }
9acda34c 329 }
330 }
331
83d66053 332 // We need to check if there are any cluster data blocks and add their
333 // information to the AliHLTMUONRecHit objects.
334 for (block = GetFirstInputBlock(AliHLTMUONConstants::ClusterBlockDataType());
335 block != NULL;
336 block = GetNextInputBlock()
337 )
338 {
339 specification |= block->fSpecification;
340 AliHLTMUONClustersBlockReader inblock(block->fPtr, block->fSize);
341 if (not BlockStructureOk(inblock))
342 {
343 if (DumpDataOnError()) DumpEvent(evtData, trigData);
344 continue;
345 }
346
347 for (AliHLTUInt32_t n = 0; n < inblock.Nentries(); n++)
348 {
349 const AliHLTMUONClusterStruct& clust = inblock[n];
350
351 AliHLTUInt8_t chamber;
352 AliHLTUInt16_t detElemId;
353 AliHLTMUONUtils::UnpackRecHitFlags(clust.fHit.fFlags, chamber, detElemId);
354 if (clust.fDetElemId != detElemId)
355 {
356 HLTWarning("Found a cluster with a different detector element ID (%d)"
357 " from its corresponding hit (x,y,z = %f,%f,%f and detElemId = %d).",
358 clust.fDetElemId,
359 clust.fHit.fX, clust.fHit.fY, clust.fHit.fZ,
360 detElemId
361 );
362 }
363
364 // Try find the corresponding reconstructed hit in 'event'.
365 AliHLTMUONRecHit* hit = NULL;
366 for (Int_t k = 0; k < event.Array().GetEntriesFast(); k++)
367 {
368 if (event.Array()[k]->IsA() != AliHLTMUONRecHit::Class())
369 continue;
370 AliHLTMUONRecHit* h = static_cast<AliHLTMUONRecHit*>(event.Array()[k]);
371 if (h->DetElemId() == detElemId and h->X() == clust.fHit.fX
372 and h->Y() == clust.fHit.fY and h->Z() == clust.fHit.fZ)
373 {
374 hit = h;
375 break;
376 }
377 }
378
379 // If we could not find the corresponding hit then we need to create
380 // a new hit object, otherwise we can just append the information.
381 if (hit == NULL)
382 {
383 // Decode the source DDL from the specification bits.
384 Int_t sourceDDL = -1;
385 bool ddl[22];
386 AliHLTMUONUtils::UnpackSpecBits(block->fSpecification, ddl);
387 for (int k = 0; k < 22; k++)
388 {
389 if (ddl[k])
390 {
391 if (sourceDDL == -1)
392 {
393 sourceDDL = k+1;
394 }
395 else
396 {
397 HLTWarning("An input block of cluster data contains"
398 " data from multiple DDL sources."
399 );
400 }
401 }
402 }
403 if (sourceDDL > 20)
404 {
405 HLTWarning("The source DDL of a cluster data input block is %d."
406 " The expected range for the DDL is [1..20].",
407 sourceDDL
408 );
409 }
410 event.Add(new AliHLTMUONRecHit(
411 clust.fHit.fX, clust.fHit.fY, clust.fHit.fZ,
412 sourceDDL, detElemId
413 ));
414 }
415 else
416 {
417 hit->SetDebugInfo(
66622a82 418 detElemId, clust.fId,
419 clust.fNchannelsB, clust.fNchannelsNB,
420 clust.fChargeB, clust.fChargeNB,
421 hit->SourceDDL()
83d66053 422 );
423 }
424 }
425 }
426
9acda34c 427 // Now we can look for tracks to add. We needed the ROOT trigger records
428 // and reco hits created before we can create track objects.
450e0b36 429 for (block = GetFirstInputBlock(AliHLTMUONConstants::MansoTracksBlockDataType());
430 block != NULL;
431 block = GetNextInputBlock()
432 )
9acda34c 433 {
649ab027 434 specification |= block->fSpecification;
3240b3ce 435 AliHLTMUONMansoTracksBlockReader inblock(block->fPtr, block->fSize);
ffb64d3e 436 if (not BlockStructureOk(inblock))
437 {
438 if (DumpDataOnError()) DumpEvent(evtData, trigData);
439 continue;
440 }
450e0b36 441
442 for (AliHLTUInt32_t n = 0; n < inblock.Nentries(); n++)
443 {
444 const AliHLTMUONMansoTrackStruct& t = inblock[n];
445
446 AliHLTMUONParticleSign sign;
447 bool hitset[4];
448 AliHLTMUONUtils::UnpackMansoTrackFlags(
449 t.fFlags, sign, hitset
450 );
451
452 // Try find the trigger record in 'event'.
453 const AliHLTMUONTriggerRecord* trigrec = NULL;
454 for (Int_t k = 0; k < event.Array().GetEntriesFast(); k++)
9acda34c 455 {
450e0b36 456 if (event.Array()[k]->IsA() != AliHLTMUONTriggerRecord::Class())
457 continue;
458 const AliHLTMUONTriggerRecord* tk =
459 static_cast<const AliHLTMUONTriggerRecord*>(event.Array()[k]);
460 if (tk->Id() == t.fTrigRec)
9acda34c 461 {
450e0b36 462 trigrec = tk;
463 break;
9acda34c 464 }
450e0b36 465 }
466
467 // Now try find the hits in 'event'.
468 // If they cannot be found then create new ones.
469 const AliHLTMUONRecHit* hit7 = NULL;
470 const AliHLTMUONRecHit* hit8 = NULL;
471 const AliHLTMUONRecHit* hit9 = NULL;
472 const AliHLTMUONRecHit* hit10 = NULL;
473 for (Int_t k = 0; k < event.Array().GetEntriesFast(); k++)
474 {
475 if (event.Array()[k]->IsA() != AliHLTMUONRecHit::Class())
476 continue;
477 const AliHLTMUONRecHit* h =
478 static_cast<const AliHLTMUONRecHit*>(event.Array()[k]);
9acda34c 479
450e0b36 480 if (hitset[0] and h->X() == t.fHit[0].fX and h->Y() == t.fHit[0].fY
481 and h->Z() == t.fHit[0].fZ)
9acda34c 482 {
450e0b36 483 hit7 = h;
9acda34c 484 }
450e0b36 485 if (hitset[1] and h->X() == t.fHit[1].fX and h->Y() == t.fHit[1].fY
486 and h->Z() == t.fHit[1].fZ)
9acda34c 487 {
450e0b36 488 hit8 = h;
9acda34c 489 }
450e0b36 490 if (hitset[2] and h->X() == t.fHit[2].fX and h->Y() == t.fHit[2].fY
491 and h->Z() == t.fHit[2].fZ)
9acda34c 492 {
450e0b36 493 hit9 = h;
9acda34c 494 }
450e0b36 495 if (hitset[3] and h->X() == t.fHit[3].fX and h->Y() == t.fHit[3].fY
496 and h->Z() == t.fHit[3].fZ)
9acda34c 497 {
450e0b36 498 hit10 = h;
9acda34c 499 }
450e0b36 500 }
501 AliHLTMUONRecHit* newhit;
502 if (hitset[0] and hit7 == NULL)
503 {
504 newhit = new AliHLTMUONRecHit(t.fHit[0].fX, t.fHit[0].fY, t.fHit[0].fZ);
505 event.Add(newhit);
506 hit7 = newhit;
507 }
508 if (hitset[1] and hit8 == NULL)
509 {
510 newhit = new AliHLTMUONRecHit(t.fHit[1].fX, t.fHit[1].fY, t.fHit[1].fZ);
511 event.Add(newhit);
512 hit8 = newhit;
513 }
514 if (hitset[2] and hit9 == NULL)
515 {
516 newhit = new AliHLTMUONRecHit(t.fHit[2].fX, t.fHit[2].fY, t.fHit[2].fZ);
517 event.Add(newhit);
518 hit9 = newhit;
519 }
520 if (hitset[3] and hit10 == NULL)
521 {
522 newhit = new AliHLTMUONRecHit(t.fHit[3].fX, t.fHit[3].fY, t.fHit[3].fZ);
523 event.Add(newhit);
524 hit10 = newhit;
525 }
526
527 AliHLTMUONMansoTrack* tr = new AliHLTMUONMansoTrack(
528 t.fId, sign, t.fPx, t.fPy, t.fPz, t.fChi2,
529 trigrec, hit7, hit8, hit9, hit10
530 );
531 event.Add(tr);
532 }
533 }
534
8e0220c2 535 bool decisionBlockFound = false;
450e0b36 536 UInt_t numLowPt = 0;
537 UInt_t numHighPt = 0;
538 TClonesArray singlesDecisions("AliHLTMUONDecision::AliTrackDecision");
539
540 // Find the single tracks decision blocks and add their information.
541 // We just sum the trigger scalars and single decisions.
542 for (block = GetFirstInputBlock(AliHLTMUONConstants::SinglesDecisionBlockDataType());
543 block != NULL;
544 block = GetNextInputBlock()
545 )
546 {
8e0220c2 547 decisionBlockFound = true;
649ab027 548 specification |= block->fSpecification;
3240b3ce 549 AliHLTMUONSinglesDecisionBlockReader inblock(block->fPtr, block->fSize);
ffb64d3e 550 if (not BlockStructureOk(inblock))
551 {
552 if (DumpDataOnError()) DumpEvent(evtData, trigData);
553 continue;
554 }
450e0b36 555
556 numLowPt += inblock.BlockHeader().fNlowPt;
557 numHighPt += inblock.BlockHeader().fNhighPt;
558
559 for (AliHLTUInt32_t n = 0; n < inblock.Nentries(); n++)
560 {
561 const AliHLTMUONTrackDecisionStruct& t = inblock[n];
562
563 bool highPt, lowPt;
564 AliHLTMUONUtils::UnpackTrackDecisionBits(t.fTriggerBits, highPt, lowPt);
565
566 // Try find the corresponding track in the 'event'.
567 const AliHLTMUONMansoTrack* track = NULL;
568 for (Int_t k = 0; k < event.Array().GetEntriesFast(); k++)
569 {
570 if (event.Array()[k]->IsA() != AliHLTMUONMansoTrack::Class())
571 continue;
572 const AliHLTMUONMansoTrack* tk =
573 static_cast<const AliHLTMUONMansoTrack*>(event.Array()[k]);
574 if (tk->Id() == t.fTrackId)
9acda34c 575 {
450e0b36 576 track = tk;
577 break;
9acda34c 578 }
450e0b36 579 }
9acda34c 580
450e0b36 581 // If the track was not found then create a dummy one.
582 if (track == NULL)
583 {
584 AliHLTMUONMansoTrack* tr = new AliHLTMUONMansoTrack(t.fTrackId);
9acda34c 585 event.Add(tr);
450e0b36 586 track = tr;
9acda34c 587 }
450e0b36 588
589 new (singlesDecisions[singlesDecisions.GetEntriesFast()])
590 AliHLTMUONDecision::AliTrackDecision(t.fPt, lowPt, highPt, track);
9acda34c 591 }
450e0b36 592 }
593
594 UInt_t numUnlikeAnyPt = 0;
595 UInt_t numUnlikeLowPt = 0;
596 UInt_t numUnlikeHighPt = 0;
597 UInt_t numLikeAnyPt = 0;
598 UInt_t numLikeLowPt = 0;
599 UInt_t numLikeHighPt = 0;
600 UInt_t numAnyMass = 0;
601 UInt_t numLowMass = 0;
602 UInt_t numHighMass = 0;
603 TClonesArray pairsDecisions("AliHLTMUONDecision::AliPairDecision");
604
605 // Find the track pairs decision blocks and add their information.
606 // We just sum the trigger scalars and track pair decisions.
607 for (block = GetFirstInputBlock(AliHLTMUONConstants::PairsDecisionBlockDataType());
608 block != NULL;
609 block = GetNextInputBlock()
610 )
611 {
8e0220c2 612 decisionBlockFound = true;
649ab027 613 specification |= block->fSpecification;
3240b3ce 614 AliHLTMUONPairsDecisionBlockReader inblock(block->fPtr, block->fSize);
ffb64d3e 615 if (not BlockStructureOk(inblock))
616 {
617 if (DumpDataOnError()) DumpEvent(evtData, trigData);
618 continue;
619 }
450e0b36 620
621 numUnlikeAnyPt += inblock.BlockHeader().fNunlikeAnyPt;
622 numUnlikeLowPt += inblock.BlockHeader().fNunlikeLowPt;
623 numUnlikeHighPt += inblock.BlockHeader().fNunlikeHighPt;
624 numLikeAnyPt += inblock.BlockHeader().fNlikeAnyPt;
625 numLikeLowPt += inblock.BlockHeader().fNlikeLowPt;
626 numLikeHighPt += inblock.BlockHeader().fNlikeHighPt;
627 numAnyMass += inblock.BlockHeader().fNmassAny;
628 numLowMass += inblock.BlockHeader().fNmassLow;
629 numHighMass += inblock.BlockHeader().fNmassHigh;
630
631 for (AliHLTUInt32_t n = 0; n < inblock.Nentries(); n++)
632 {
633 const AliHLTMUONPairDecisionStruct& t = inblock[n];
634
635 bool highMass, lowMass, unlike;
636 AliHLTUInt8_t highPtCount, lowPtCount;
637 AliHLTMUONUtils::UnpackPairDecisionBits(
638 t.fTriggerBits, highMass, lowMass, unlike,
639 highPtCount, lowPtCount
640 );
641
642 // Try find the corresponding tracks in the 'event'.
643 const AliHLTMUONMansoTrack* trackA = NULL;
644 const AliHLTMUONMansoTrack* trackB = NULL;
645 for (Int_t k = 0; k < event.Array().GetEntriesFast(); k++)
646 {
647 if (event.Array()[k]->IsA() != AliHLTMUONMansoTrack::Class())
648 continue;
649 const AliHLTMUONMansoTrack* tk =
650 static_cast<const AliHLTMUONMansoTrack*>(event.Array()[k]);
651 if (tk->Id() == t.fTrackAId) trackA = tk;
652 if (tk->Id() == t.fTrackBId) trackB = tk;
653 if (trackA != NULL and trackB != NULL) break;
654 }
655
656 // If either of the tracks was not found then create a dummy one.
657 if (trackA == NULL)
658 {
659 AliHLTMUONMansoTrack* tr = new AliHLTMUONMansoTrack(t.fTrackAId);
660 event.Add(tr);
661 trackA = tr;
662 }
663 if (trackB == NULL)
664 {
665 AliHLTMUONMansoTrack* tr = new AliHLTMUONMansoTrack(t.fTrackBId);
666 event.Add(tr);
667 trackB = tr;
668 }
669
670 new (pairsDecisions[pairsDecisions.GetEntriesFast()])
671 AliHLTMUONDecision::AliPairDecision(
672 t.fInvMass, lowMass, highMass, unlike,
673 lowPtCount, highPtCount, trackA, trackB
674 );
675 }
676 }
677
8e0220c2 678
679 // Do not add the decision if no decision blocks were found.
680 if (decisionBlockFound)
450e0b36 681 {
8e0220c2 682 AliHLTMUONDecision* triggerDecision = new AliHLTMUONDecision(
683 numLowPt, numHighPt, numUnlikeAnyPt, numUnlikeLowPt,
684 numUnlikeHighPt, numLikeAnyPt, numLikeLowPt,
685 numLikeHighPt, numAnyMass, numLowMass, numHighMass
686 );
687 for (Int_t i = 0; i < singlesDecisions.GetEntriesFast(); i++)
688 {
689 AliHLTMUONDecision::AliTrackDecision* decision =
690 static_cast<AliHLTMUONDecision::AliTrackDecision*>( singlesDecisions[i] );
691 triggerDecision->AddDecision(decision);
692 }
693 for (Int_t j = 0; j < pairsDecisions.GetEntriesFast(); j++)
694 {
695 AliHLTMUONDecision::AliPairDecision* decision =
696 static_cast<AliHLTMUONDecision::AliPairDecision*>( pairsDecisions[j] );
697 triggerDecision->AddDecision(decision);
698 }
699
700 event.Add(triggerDecision);
450e0b36 701 }
9acda34c 702
73ed798e 703 PushBack(&event, AliHLTMUONConstants::RootifiedEventDataType(), specification);
9acda34c 704
705 return 0;
706}
6253e09b 707