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