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