added Save function (X. Lopez)
[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"
462e3880 35#include "AliMUONTriggerDDLDecoderEventHandler.h"
450e0b36 36#include "TClonesArray.h"
9acda34c 37#include <cassert>
462e3880 38#include <map>
9acda34c 39
9acda34c 40ClassImp(AliHLTMUONRootifierComponent);
41
42
43AliHLTMUONRootifierComponent::AliHLTMUONRootifierComponent() :
154cba94 44 AliHLTMUONProcessor(),
450e0b36 45 fWarnForUnexpecedBlock(false)
9acda34c 46{
6253e09b 47 ///
48 /// Default constructor.
49 ///
9acda34c 50}
51
52
53AliHLTMUONRootifierComponent::~AliHLTMUONRootifierComponent()
54{
6253e09b 55 ///
56 /// Default destructor.
57 ///
9acda34c 58}
59
60
ffb64d3e 61bool AliHLTMUONRootifierComponent::IgnoreArgument(const char* arg) const
62{
63 /// Return true if the argument is one of -cdbpath -run or -delaysetup
64 /// to prevent the parent class from parsing these arguments in DoInit.
65
558cf470 66 if (strcmp(arg, "-cdbpath") == 0 or strcmp(arg, "-run") == 0 or
67 strcmp(arg, "-delaysetup") == 0)
ffb64d3e 68 {
69 return true;
70 }
71 else
72 {
73 return false;
74 }
75}
76
77
450e0b36 78int AliHLTMUONRootifierComponent::DoInit(int argc, const char** argv)
9acda34c 79{
6253e09b 80 ///
81 /// Inherited from AliHLTComponent.
82 /// Parses the command line parameters and initialises the component.
83 ///
84
450e0b36 85 HLTInfo("Initialising dHLT rootifier component.");
ffb64d3e 86
87 // Inherit the parents functionality.
88 int result = AliHLTMUONProcessor::DoInit(argc, argv);
89 if (result != 0) return result;
450e0b36 90
91 fWarnForUnexpecedBlock = false;
92
93 for (int i = 0; i < argc; i++)
94 {
ffb64d3e 95 if (ArgumentAlreadyHandled(i, argv[i])) continue;
96
450e0b36 97 if (strcmp(argv[i], "-warn_on_unexpected_block") == 0)
98 {
99 fWarnForUnexpecedBlock = true;
100 continue;
101 }
102
103 HLTError("Unknown option '%s'.", argv[i]);
104 return -EINVAL;
105 }
106
9acda34c 107 return 0;
108}
109
110
111int AliHLTMUONRootifierComponent::DoDeinit()
112{
6253e09b 113 ///
114 /// Inherited from AliHLTComponent. Performs a cleanup of the component.
115 ///
116
450e0b36 117 HLTInfo("Deinitialising dHLT rootifier component.");
9acda34c 118 return 0;
119}
120
121
122const char* AliHLTMUONRootifierComponent::GetComponentID()
123{
6253e09b 124 ///
125 /// Inherited from AliHLTComponent. Returns the component ID.
126 ///
127
450e0b36 128 return AliHLTMUONConstants::RootifierComponentId();
9acda34c 129}
130
131
132AliHLTComponentDataType AliHLTMUONRootifierComponent::GetOutputDataType()
133{
bb14e9db 134 /// Inherited from AliHLTComponent. Returns kAliHLTMultipleDataType
135 /// refer to GetOutputDataTypes for all returned data types.
136
137 return kAliHLTMultipleDataType;
138}
139
140
141int AliHLTMUONRootifierComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList)
142{
143 /// Inherited from AliHLTComponent. Returns the output data types.
6253e09b 144
1d8ae082 145 tgtList.push_back(AliHLTMUONConstants::RootifiedEventDataType());
62a08849 146 return tgtList.size();
9acda34c 147}
148
149
ffb64d3e 150void AliHLTMUONRootifierComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list)
9acda34c 151{
6253e09b 152 ///
153 /// Inherited from AliHLTProcessor. Returns the list of expected input data types.
154 ///
155
9acda34c 156 list.push_back(kAliHLTAnyDataType);
157}
158
159
160void AliHLTMUONRootifierComponent::GetOutputDataSize(
161 unsigned long& constBase, double& inputMultiplier
162 )
163{
6253e09b 164 ///
165 /// Inherited from AliHLTComponent. Returns an estimate of the expected output data size.
166 ///
167
477135e2 168 constBase = 1024*1024;
169 inputMultiplier = 100;
9acda34c 170}
171
172
173AliHLTComponent* AliHLTMUONRootifierComponent::Spawn()
174{
6253e09b 175 ///
176 /// Inherited from AliHLTComponent. Creates a new object instance.
177 ///
178
9acda34c 179 return new AliHLTMUONRootifierComponent();
180}
181
182
183int AliHLTMUONRootifierComponent::DoEvent(
184 const AliHLTComponentEventData& evtData,
ffb64d3e 185 AliHLTComponentTriggerData& trigData
9acda34c 186 )
187{
6253e09b 188 ///
189 /// Inherited from AliHLTProcessor. Processes the new event data.
190 ///
191
83d66053 192 if (not IsDataEvent()) return 0;
193
9acda34c 194 AliHLTMUONEvent event(evtData.fEventID);
450e0b36 195 const AliHLTComponentBlockData* block = NULL;
649ab027 196 AliHLTUInt32_t specification = 0; // Contains the output data block spec bits.
462e3880 197 std::map<AliHLTInt32_t, AliHLTMUONTriggerRecord*> triggerMap;
9acda34c 198
199 // First process the blocks of reconstructed hits and trigger records.
200 for (int i = 0; i < GetNumberOfInputBlocks(); i++)
201 {
450e0b36 202 block = GetInputBlock(i);
9acda34c 203 assert( block != NULL );
450e0b36 204
205 HLTDebug("Handling block: %u, with fDataType = '%s', fPtr = %p and fSize = %u bytes.",
a62ffb4d 206 i, DataType2Text(block->fDataType).c_str(), block->fPtr, block->fSize
450e0b36 207 );
208
9acda34c 209 if (block->fDataType == AliHLTMUONConstants::RecHitsBlockDataType())
210 {
649ab027 211 specification |= block->fSpecification;
3240b3ce 212 AliHLTMUONRecHitsBlockReader inblock(block->fPtr, block->fSize);
ffb64d3e 213 if (not BlockStructureOk(inblock))
214 {
215 if (DumpDataOnError()) DumpEvent(evtData, trigData);
216 continue;
217 }
9acda34c 218
219 // Decode the source DDL from the specification bits.
220 Int_t sourceDDL = -1;
221 bool ddl[22];
222 AliHLTMUONUtils::UnpackSpecBits(block->fSpecification, ddl);
223 for (int k = 0; k < 22; k++)
224 {
225 if (ddl[k])
226 {
227 if (sourceDDL == -1)
228 {
229 sourceDDL = k+1;
230 }
231 else
232 {
233 HLTWarning("The input data block %d contains"
234 " data from multiple DDL sources.", i
235 );
236 }
237 }
238 }
239 if (sourceDDL > 20)
240 {
241 HLTWarning("The source DDL for input data block %d is %d."
242 " The expected range for the DDL is [1..20].",
243 i, sourceDDL
244 );
245 }
246
247 for (AliHLTUInt32_t n = 0; n < inblock.Nentries(); n++)
248 {
249 const AliHLTMUONRecHitStruct& h = inblock[n];
cdd0c63d 250 AliHLTUInt8_t chamber;
251 AliHLTUInt16_t detElemId;
252 AliHLTMUONUtils::UnpackRecHitFlags(h.fFlags, chamber, detElemId);
83d66053 253 event.Add(new AliHLTMUONRecHit(h.fX, h.fY, h.fZ, sourceDDL, detElemId));
9acda34c 254 }
255 }
256 else if (block->fDataType == AliHLTMUONConstants::TriggerRecordsBlockDataType())
257 {
649ab027 258 specification |= block->fSpecification;
3240b3ce 259 AliHLTMUONTriggerRecordsBlockReader inblock(block->fPtr, block->fSize);
ffb64d3e 260 if (not BlockStructureOk(inblock))
261 {
262 if (DumpDataOnError()) DumpEvent(evtData, trigData);
263 continue;
264 }
9acda34c 265
266 // Decode the source DDL from the specification bits.
267 Int_t sourceDDL = -1;
268 bool ddl[22];
269 AliHLTMUONUtils::UnpackSpecBits(block->fSpecification, ddl);
270 for (int k = 0; k < 22; k++)
271 {
272 if (ddl[k])
273 {
274 if (sourceDDL == -1)
275 {
276 sourceDDL = k+1;
277 }
278 else
279 {
280 HLTWarning("The input data block %d contains"
281 " data from multiple DDL sources.", i
282 );
283 }
284 }
285 }
bb14e9db 286 if (sourceDDL != -1 and (sourceDDL < 21 or sourceDDL > 22))
9acda34c 287 {
288 HLTWarning("The source DDL for input data block %d is %d."
289 " The expected range for the DDL is [21..22].",
290 i, sourceDDL
291 );
292 }
293
294 for (AliHLTUInt32_t n = 0; n < inblock.Nentries(); n++)
295 {
296 const AliHLTMUONTriggerRecordStruct& t = inblock[n];
297
298 AliHLTMUONParticleSign sign;
299 bool hitset[4];
300 AliHLTMUONUtils::UnpackTriggerRecordFlags(
301 t.fFlags, sign, hitset
302 );
303
304 AliHLTMUONTriggerRecord* tr = new AliHLTMUONTriggerRecord(
305 t.fId, sign, t.fPx, t.fPy, t.fPz, sourceDDL
306 );
307 for (int k = 0; k < 4; k++)
462e3880 308 {
309 Int_t detElemId = AliHLTMUONUtils::GetDetElemIdFromFlags(t.fHit[k].fFlags);
310 tr->SetHit(k+11, t.fHit[k].fX, t.fHit[k].fY, t.fHit[k].fZ, detElemId);
311 }
9acda34c 312 event.Add(tr);
462e3880 313 triggerMap[t.fId] = tr;
9acda34c 314 }
315 }
316 else
317 {
462e3880 318 if (block->fDataType != AliHLTMUONConstants::TrigRecsDebugBlockDataType() and
319 block->fDataType != AliHLTMUONConstants::ClusterBlockDataType() and
320 block->fDataType != AliHLTMUONConstants::ChannelBlockDataType() and
321 block->fDataType != AliHLTMUONConstants::MansoTracksBlockDataType() and
322 block->fDataType != AliHLTMUONConstants::MansoCandidatesBlockDataType() and
450e0b36 323 block->fDataType != AliHLTMUONConstants::SinglesDecisionBlockDataType() and
324 block->fDataType != AliHLTMUONConstants::PairsDecisionBlockDataType()
325 )
326 {
327 // Log a message indicating that we got a data block that we
328 // do not know how to handle.
329 if (fWarnForUnexpecedBlock)
330 HLTWarning("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
331 DataType2Text(block->fDataType).c_str(), block->fSpecification
332 );
4e22efc4 333#ifdef __DEBUG
450e0b36 334 else
335 HLTDebug("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
336 DataType2Text(block->fDataType).c_str(), block->fSpecification
337 );
4e22efc4 338#endif
450e0b36 339 }
9acda34c 340 }
341 }
342
462e3880 343 // We need to check if there are any trigger record debug data blocks
344 // and add their information to the AliHLTMUONTriggerRecord objects.
345 for (block = GetFirstInputBlock(AliHLTMUONConstants::TrigRecsDebugBlockDataType());
346 block != NULL;
347 block = GetNextInputBlock()
348 )
349 {
350 specification |= block->fSpecification;
351 AliHLTMUONTrigRecsDebugBlockReader inblock(block->fPtr, block->fSize);
352 if (not BlockStructureOk(inblock))
353 {
354 if (DumpDataOnError()) DumpEvent(evtData, trigData);
355 continue;
356 }
357
358 for (AliHLTUInt32_t n = 0; n < inblock.Nentries(); n++)
359 {
360 const AliHLTMUONTrigRecInfoStruct& triginfo = inblock[n];
361
362 AliHLTMUONTriggerRecord* trigrec = triggerMap[triginfo.fTrigRecId];
363 if (trigrec == NULL)
364 {
365 // Decode the source DDL from the specification bits.
366 Int_t sourceDDL = -1;
367 bool ddl[22];
368 AliHLTMUONUtils::UnpackSpecBits(block->fSpecification, ddl);
369 for (int k = 0; k < 22; k++)
370 {
371 if (ddl[k])
372 {
373 if (sourceDDL == -1)
374 {
375 sourceDDL = k+1;
376 }
377 else
378 {
379 HLTWarning("An trigger debug information data block"
380 " contains data from multiple DDL sources."
381 );
382 }
383 }
384 }
385 if (sourceDDL != -1 and (sourceDDL < 21 or sourceDDL > 22))
386 {
387 HLTWarning("The source DDL for a trigger debug information data"
388 " block is %d. The expected range for the DDL is [21..22].",
389 sourceDDL
390 );
391 }
392
393 trigrec = new AliHLTMUONTriggerRecord(
394 0, 0, 0, 0, 0, sourceDDL
395 );
396 }
397
398 for (Int_t j = 0; j < 4; ++j)
399 {
400 if (triginfo.fDetElemId[j] != trigrec->DetElemId(j+11))
401 {
402 HLTWarning("Found a trigger record with a hit on chamber %d with a different"
403 " detector element ID %d than the debug information %d.",
404 j, trigrec->DetElemId(j+11), triginfo.fDetElemId[j]
405 );
406 }
407 }
408
409 typedef AliMUONTriggerDDLDecoderEventHandler Handler;
410
411 trigrec->SetDebugInfo(triginfo.fZmiddle, triginfo.fBl);
412
413 UShort_t patternX[4][3] = {
414 {
415 Handler::GetLocalX1(&triginfo.fL0StructPrev),
416 Handler::GetLocalX1(&triginfo.fL0Struct),
417 Handler::GetLocalX1(&triginfo.fL0StructNext)
418 },{
419 Handler::GetLocalX2(&triginfo.fL0StructPrev),
420 Handler::GetLocalX2(&triginfo.fL0Struct),
421 Handler::GetLocalX2(&triginfo.fL0StructNext)
422 },{
423 Handler::GetLocalX3(&triginfo.fL0StructPrev),
424 Handler::GetLocalX3(&triginfo.fL0Struct),
425 Handler::GetLocalX3(&triginfo.fL0StructNext)
426 },{
427 Handler::GetLocalX4(&triginfo.fL0StructPrev),
428 Handler::GetLocalX4(&triginfo.fL0Struct),
429 Handler::GetLocalX4(&triginfo.fL0StructNext)
430 }
431 };
432 UShort_t patternY[4][3] = {
433 {
434 Handler::GetLocalY1(&triginfo.fL0StructPrev),
435 Handler::GetLocalY1(&triginfo.fL0Struct),
436 Handler::GetLocalY1(&triginfo.fL0StructNext)
437 },{
438 Handler::GetLocalY2(&triginfo.fL0StructPrev),
439 Handler::GetLocalY2(&triginfo.fL0Struct),
440 Handler::GetLocalY2(&triginfo.fL0StructNext)
441 },{
442 Handler::GetLocalY3(&triginfo.fL0StructPrev),
443 Handler::GetLocalY3(&triginfo.fL0Struct),
444 Handler::GetLocalY3(&triginfo.fL0StructNext)
445 },{
446 Handler::GetLocalY4(&triginfo.fL0StructPrev),
447 Handler::GetLocalY4(&triginfo.fL0Struct),
448 Handler::GetLocalY4(&triginfo.fL0StructNext)
449 }
450 };
451
452 for (Int_t j = 0; j < 4; ++j)
453 {
454 trigrec->SetHitDebugInfo(j+11, patternX[j], patternY[j]);
455 }
456 }
457 }
458
459 std::map<AliHLTInt32_t, AliHLTMUONRecHit*> clusterMap;
460
83d66053 461 // We need to check if there are any cluster data blocks and add their
462 // information to the AliHLTMUONRecHit objects.
463 for (block = GetFirstInputBlock(AliHLTMUONConstants::ClusterBlockDataType());
464 block != NULL;
465 block = GetNextInputBlock()
466 )
467 {
468 specification |= block->fSpecification;
469 AliHLTMUONClustersBlockReader inblock(block->fPtr, block->fSize);
470 if (not BlockStructureOk(inblock))
471 {
472 if (DumpDataOnError()) DumpEvent(evtData, trigData);
473 continue;
474 }
475
476 for (AliHLTUInt32_t n = 0; n < inblock.Nentries(); n++)
477 {
478 const AliHLTMUONClusterStruct& clust = inblock[n];
479
480 AliHLTUInt8_t chamber;
481 AliHLTUInt16_t detElemId;
482 AliHLTMUONUtils::UnpackRecHitFlags(clust.fHit.fFlags, chamber, detElemId);
483 if (clust.fDetElemId != detElemId)
484 {
485 HLTWarning("Found a cluster with a different detector element ID (%d)"
486 " from its corresponding hit (x,y,z = %f,%f,%f and detElemId = %d).",
487 clust.fDetElemId,
488 clust.fHit.fX, clust.fHit.fY, clust.fHit.fZ,
489 detElemId
490 );
491 }
492
493 // Try find the corresponding reconstructed hit in 'event'.
494 AliHLTMUONRecHit* hit = NULL;
495 for (Int_t k = 0; k < event.Array().GetEntriesFast(); k++)
496 {
497 if (event.Array()[k]->IsA() != AliHLTMUONRecHit::Class())
498 continue;
499 AliHLTMUONRecHit* h = static_cast<AliHLTMUONRecHit*>(event.Array()[k]);
500 if (h->DetElemId() == detElemId and h->X() == clust.fHit.fX
501 and h->Y() == clust.fHit.fY and h->Z() == clust.fHit.fZ)
502 {
503 hit = h;
504 break;
505 }
506 }
507
508 // If we could not find the corresponding hit then we need to create
509 // a new hit object, otherwise we can just append the information.
510 if (hit == NULL)
511 {
512 // Decode the source DDL from the specification bits.
513 Int_t sourceDDL = -1;
514 bool ddl[22];
515 AliHLTMUONUtils::UnpackSpecBits(block->fSpecification, ddl);
516 for (int k = 0; k < 22; k++)
517 {
518 if (ddl[k])
519 {
520 if (sourceDDL == -1)
521 {
522 sourceDDL = k+1;
523 }
524 else
525 {
526 HLTWarning("An input block of cluster data contains"
527 " data from multiple DDL sources."
528 );
529 }
530 }
531 }
532 if (sourceDDL > 20)
533 {
534 HLTWarning("The source DDL of a cluster data input block is %d."
535 " The expected range for the DDL is [1..20].",
536 sourceDDL
537 );
538 }
462e3880 539 hit = new AliHLTMUONRecHit(
83d66053 540 clust.fHit.fX, clust.fHit.fY, clust.fHit.fZ,
541 sourceDDL, detElemId
462e3880 542 );
543 event.Add(hit);
83d66053 544 }
545 else
546 {
547 hit->SetDebugInfo(
66622a82 548 detElemId, clust.fId,
549 clust.fNchannelsB, clust.fNchannelsNB,
550 clust.fChargeB, clust.fChargeNB,
551 hit->SourceDDL()
83d66053 552 );
553 }
462e3880 554
555 clusterMap[clust.fId] = hit;
556 }
557 }
558
559 // We need to check if there are any channel data blocks and add their
560 // information to the AliHLTMUONRecHit objects.
561 for (block = GetFirstInputBlock(AliHLTMUONConstants::ChannelBlockDataType());
562 block != NULL;
563 block = GetNextInputBlock()
564 )
565 {
566 specification |= block->fSpecification;
567 AliHLTMUONChannelsBlockReader inblock(block->fPtr, block->fSize);
568 if (not BlockStructureOk(inblock))
569 {
570 if (DumpDataOnError()) DumpEvent(evtData, trigData);
571 continue;
572 }
573
574 for (AliHLTUInt32_t n = 0; n < inblock.Nentries(); n++)
575 {
576 const AliHLTMUONChannelStruct& channel = inblock[n];
577
578 AliHLTMUONRecHit* hit = clusterMap[channel.fClusterId];
579 if (hit == NULL)
580 {
581 // Decode the source DDL from the specification bits.
582 Int_t sourceDDL = -1;
583 bool ddl[22];
584 AliHLTMUONUtils::UnpackSpecBits(block->fSpecification, ddl);
585 for (int k = 0; k < 22; k++)
586 {
587 if (ddl[k])
588 {
589 if (sourceDDL == -1)
590 {
591 sourceDDL = k+1;
592 }
593 else
594 {
595 HLTWarning("An input block of cluster data contains"
596 " data from multiple DDL sources."
597 );
598 }
599 }
600 }
601 if (sourceDDL > 20)
602 {
603 HLTWarning("The source DDL of a cluster data input block is %d."
604 " The expected range for the DDL is [1..20].",
605 sourceDDL
606 );
607 }
608 hit = new AliHLTMUONRecHit(0, 0, 0, sourceDDL, -1);
609 event.Add(hit);
610 }
611
612 hit->AddChannel(
613 channel.fBusPatch, channel.fManu,
614 channel.fChannelAddress, channel.fSignal,
615 channel.fRawDataWord
616 );
83d66053 617 }
618 }
619
9acda34c 620 // Now we can look for tracks to add. We needed the ROOT trigger records
621 // and reco hits created before we can create track objects.
450e0b36 622 for (block = GetFirstInputBlock(AliHLTMUONConstants::MansoTracksBlockDataType());
623 block != NULL;
624 block = GetNextInputBlock()
625 )
9acda34c 626 {
649ab027 627 specification |= block->fSpecification;
3240b3ce 628 AliHLTMUONMansoTracksBlockReader inblock(block->fPtr, block->fSize);
ffb64d3e 629 if (not BlockStructureOk(inblock))
630 {
631 if (DumpDataOnError()) DumpEvent(evtData, trigData);
632 continue;
633 }
450e0b36 634
635 for (AliHLTUInt32_t n = 0; n < inblock.Nentries(); n++)
636 {
637 const AliHLTMUONMansoTrackStruct& t = inblock[n];
638
639 AliHLTMUONParticleSign sign;
640 bool hitset[4];
641 AliHLTMUONUtils::UnpackMansoTrackFlags(
642 t.fFlags, sign, hitset
643 );
644
645 // Try find the trigger record in 'event'.
646 const AliHLTMUONTriggerRecord* trigrec = NULL;
647 for (Int_t k = 0; k < event.Array().GetEntriesFast(); k++)
9acda34c 648 {
450e0b36 649 if (event.Array()[k]->IsA() != AliHLTMUONTriggerRecord::Class())
650 continue;
651 const AliHLTMUONTriggerRecord* tk =
652 static_cast<const AliHLTMUONTriggerRecord*>(event.Array()[k]);
653 if (tk->Id() == t.fTrigRec)
9acda34c 654 {
450e0b36 655 trigrec = tk;
656 break;
9acda34c 657 }
450e0b36 658 }
659
660 // Now try find the hits in 'event'.
661 // If they cannot be found then create new ones.
662 const AliHLTMUONRecHit* hit7 = NULL;
663 const AliHLTMUONRecHit* hit8 = NULL;
664 const AliHLTMUONRecHit* hit9 = NULL;
665 const AliHLTMUONRecHit* hit10 = NULL;
666 for (Int_t k = 0; k < event.Array().GetEntriesFast(); k++)
667 {
668 if (event.Array()[k]->IsA() != AliHLTMUONRecHit::Class())
669 continue;
670 const AliHLTMUONRecHit* h =
671 static_cast<const AliHLTMUONRecHit*>(event.Array()[k]);
9acda34c 672
450e0b36 673 if (hitset[0] and h->X() == t.fHit[0].fX and h->Y() == t.fHit[0].fY
674 and h->Z() == t.fHit[0].fZ)
9acda34c 675 {
450e0b36 676 hit7 = h;
9acda34c 677 }
450e0b36 678 if (hitset[1] and h->X() == t.fHit[1].fX and h->Y() == t.fHit[1].fY
679 and h->Z() == t.fHit[1].fZ)
9acda34c 680 {
450e0b36 681 hit8 = h;
9acda34c 682 }
450e0b36 683 if (hitset[2] and h->X() == t.fHit[2].fX and h->Y() == t.fHit[2].fY
684 and h->Z() == t.fHit[2].fZ)
9acda34c 685 {
450e0b36 686 hit9 = h;
9acda34c 687 }
450e0b36 688 if (hitset[3] and h->X() == t.fHit[3].fX and h->Y() == t.fHit[3].fY
689 and h->Z() == t.fHit[3].fZ)
9acda34c 690 {
450e0b36 691 hit10 = h;
9acda34c 692 }
450e0b36 693 }
694 AliHLTMUONRecHit* newhit;
695 if (hitset[0] and hit7 == NULL)
696 {
697 newhit = new AliHLTMUONRecHit(t.fHit[0].fX, t.fHit[0].fY, t.fHit[0].fZ);
698 event.Add(newhit);
699 hit7 = newhit;
700 }
701 if (hitset[1] and hit8 == NULL)
702 {
703 newhit = new AliHLTMUONRecHit(t.fHit[1].fX, t.fHit[1].fY, t.fHit[1].fZ);
704 event.Add(newhit);
705 hit8 = newhit;
706 }
707 if (hitset[2] and hit9 == NULL)
708 {
709 newhit = new AliHLTMUONRecHit(t.fHit[2].fX, t.fHit[2].fY, t.fHit[2].fZ);
710 event.Add(newhit);
711 hit9 = newhit;
712 }
713 if (hitset[3] and hit10 == NULL)
714 {
715 newhit = new AliHLTMUONRecHit(t.fHit[3].fX, t.fHit[3].fY, t.fHit[3].fZ);
716 event.Add(newhit);
717 hit10 = newhit;
718 }
719
720 AliHLTMUONMansoTrack* tr = new AliHLTMUONMansoTrack(
721 t.fId, sign, t.fPx, t.fPy, t.fPz, t.fChi2,
722 trigrec, hit7, hit8, hit9, hit10
723 );
724 event.Add(tr);
725 }
726 }
727
8e0220c2 728 bool decisionBlockFound = false;
450e0b36 729 UInt_t numLowPt = 0;
730 UInt_t numHighPt = 0;
731 TClonesArray singlesDecisions("AliHLTMUONDecision::AliTrackDecision");
732
733 // Find the single tracks decision blocks and add their information.
734 // We just sum the trigger scalars and single decisions.
735 for (block = GetFirstInputBlock(AliHLTMUONConstants::SinglesDecisionBlockDataType());
736 block != NULL;
737 block = GetNextInputBlock()
738 )
739 {
8e0220c2 740 decisionBlockFound = true;
649ab027 741 specification |= block->fSpecification;
3240b3ce 742 AliHLTMUONSinglesDecisionBlockReader inblock(block->fPtr, block->fSize);
ffb64d3e 743 if (not BlockStructureOk(inblock))
744 {
745 if (DumpDataOnError()) DumpEvent(evtData, trigData);
746 continue;
747 }
450e0b36 748
749 numLowPt += inblock.BlockHeader().fNlowPt;
750 numHighPt += inblock.BlockHeader().fNhighPt;
751
752 for (AliHLTUInt32_t n = 0; n < inblock.Nentries(); n++)
753 {
754 const AliHLTMUONTrackDecisionStruct& t = inblock[n];
755
756 bool highPt, lowPt;
757 AliHLTMUONUtils::UnpackTrackDecisionBits(t.fTriggerBits, highPt, lowPt);
758
759 // Try find the corresponding track in the 'event'.
760 const AliHLTMUONMansoTrack* track = NULL;
761 for (Int_t k = 0; k < event.Array().GetEntriesFast(); k++)
762 {
763 if (event.Array()[k]->IsA() != AliHLTMUONMansoTrack::Class())
764 continue;
765 const AliHLTMUONMansoTrack* tk =
766 static_cast<const AliHLTMUONMansoTrack*>(event.Array()[k]);
767 if (tk->Id() == t.fTrackId)
9acda34c 768 {
450e0b36 769 track = tk;
770 break;
9acda34c 771 }
450e0b36 772 }
9acda34c 773
450e0b36 774 // If the track was not found then create a dummy one.
775 if (track == NULL)
776 {
777 AliHLTMUONMansoTrack* tr = new AliHLTMUONMansoTrack(t.fTrackId);
9acda34c 778 event.Add(tr);
450e0b36 779 track = tr;
9acda34c 780 }
450e0b36 781
782 new (singlesDecisions[singlesDecisions.GetEntriesFast()])
783 AliHLTMUONDecision::AliTrackDecision(t.fPt, lowPt, highPt, track);
9acda34c 784 }
450e0b36 785 }
786
787 UInt_t numUnlikeAnyPt = 0;
788 UInt_t numUnlikeLowPt = 0;
789 UInt_t numUnlikeHighPt = 0;
790 UInt_t numLikeAnyPt = 0;
791 UInt_t numLikeLowPt = 0;
792 UInt_t numLikeHighPt = 0;
793 UInt_t numAnyMass = 0;
794 UInt_t numLowMass = 0;
795 UInt_t numHighMass = 0;
796 TClonesArray pairsDecisions("AliHLTMUONDecision::AliPairDecision");
797
798 // Find the track pairs decision blocks and add their information.
799 // We just sum the trigger scalars and track pair decisions.
800 for (block = GetFirstInputBlock(AliHLTMUONConstants::PairsDecisionBlockDataType());
801 block != NULL;
802 block = GetNextInputBlock()
803 )
804 {
8e0220c2 805 decisionBlockFound = true;
649ab027 806 specification |= block->fSpecification;
3240b3ce 807 AliHLTMUONPairsDecisionBlockReader inblock(block->fPtr, block->fSize);
ffb64d3e 808 if (not BlockStructureOk(inblock))
809 {
810 if (DumpDataOnError()) DumpEvent(evtData, trigData);
811 continue;
812 }
450e0b36 813
814 numUnlikeAnyPt += inblock.BlockHeader().fNunlikeAnyPt;
815 numUnlikeLowPt += inblock.BlockHeader().fNunlikeLowPt;
816 numUnlikeHighPt += inblock.BlockHeader().fNunlikeHighPt;
817 numLikeAnyPt += inblock.BlockHeader().fNlikeAnyPt;
818 numLikeLowPt += inblock.BlockHeader().fNlikeLowPt;
819 numLikeHighPt += inblock.BlockHeader().fNlikeHighPt;
820 numAnyMass += inblock.BlockHeader().fNmassAny;
821 numLowMass += inblock.BlockHeader().fNmassLow;
822 numHighMass += inblock.BlockHeader().fNmassHigh;
823
824 for (AliHLTUInt32_t n = 0; n < inblock.Nentries(); n++)
825 {
826 const AliHLTMUONPairDecisionStruct& t = inblock[n];
827
828 bool highMass, lowMass, unlike;
829 AliHLTUInt8_t highPtCount, lowPtCount;
830 AliHLTMUONUtils::UnpackPairDecisionBits(
831 t.fTriggerBits, highMass, lowMass, unlike,
832 highPtCount, lowPtCount
833 );
834
835 // Try find the corresponding tracks in the 'event'.
836 const AliHLTMUONMansoTrack* trackA = NULL;
837 const AliHLTMUONMansoTrack* trackB = NULL;
838 for (Int_t k = 0; k < event.Array().GetEntriesFast(); k++)
839 {
840 if (event.Array()[k]->IsA() != AliHLTMUONMansoTrack::Class())
841 continue;
842 const AliHLTMUONMansoTrack* tk =
843 static_cast<const AliHLTMUONMansoTrack*>(event.Array()[k]);
844 if (tk->Id() == t.fTrackAId) trackA = tk;
845 if (tk->Id() == t.fTrackBId) trackB = tk;
846 if (trackA != NULL and trackB != NULL) break;
847 }
848
849 // If either of the tracks was not found then create a dummy one.
850 if (trackA == NULL)
851 {
852 AliHLTMUONMansoTrack* tr = new AliHLTMUONMansoTrack(t.fTrackAId);
853 event.Add(tr);
854 trackA = tr;
855 }
856 if (trackB == NULL)
857 {
858 AliHLTMUONMansoTrack* tr = new AliHLTMUONMansoTrack(t.fTrackBId);
859 event.Add(tr);
860 trackB = tr;
861 }
862
863 new (pairsDecisions[pairsDecisions.GetEntriesFast()])
864 AliHLTMUONDecision::AliPairDecision(
865 t.fInvMass, lowMass, highMass, unlike,
866 lowPtCount, highPtCount, trackA, trackB
867 );
868 }
869 }
870
8e0220c2 871 // Do not add the decision if no decision blocks were found.
872 if (decisionBlockFound)
450e0b36 873 {
8e0220c2 874 AliHLTMUONDecision* triggerDecision = new AliHLTMUONDecision(
875 numLowPt, numHighPt, numUnlikeAnyPt, numUnlikeLowPt,
876 numUnlikeHighPt, numLikeAnyPt, numLikeLowPt,
877 numLikeHighPt, numAnyMass, numLowMass, numHighMass
878 );
879 for (Int_t i = 0; i < singlesDecisions.GetEntriesFast(); i++)
880 {
881 AliHLTMUONDecision::AliTrackDecision* decision =
882 static_cast<AliHLTMUONDecision::AliTrackDecision*>( singlesDecisions[i] );
883 triggerDecision->AddDecision(decision);
884 }
885 for (Int_t j = 0; j < pairsDecisions.GetEntriesFast(); j++)
886 {
887 AliHLTMUONDecision::AliPairDecision* decision =
888 static_cast<AliHLTMUONDecision::AliPairDecision*>( pairsDecisions[j] );
889 triggerDecision->AddDecision(decision);
890 }
891
892 event.Add(triggerDecision);
450e0b36 893 }
9acda34c 894
73ed798e 895 PushBack(&event, AliHLTMUONConstants::RootifiedEventDataType(), specification);
9acda34c 896
897 return 0;
898}
6253e09b 899