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