Minor changes required due to changed in AliHLTComponent.
[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   
23 /// @brief  Implementation of the AliHLTMUONRootifierComponent component.
24 ///
25
26 #include "AliHLTMUONRootifierComponent.h"
27 #include "AliHLTMUONConstants.h"
28 #include "AliHLTMUONUtils.h"
29 #include "AliHLTMUONDataBlockReader.h"
30 #include "AliHLTMUONRecHit.h"
31 #include "AliHLTMUONTriggerRecord.h"
32 #include "AliHLTMUONMansoTrack.h"
33 #include <cassert>
34
35 ClassImp(AliHLTMUONEvent);
36 ClassImp(AliHLTMUONRootifierComponent);
37
38
39 AliHLTMUONRootifierComponent::AliHLTMUONRootifierComponent() :
40         AliHLTProcessor()
41 {
42         ///
43         /// Default constructor.
44         ///
45 }
46
47
48 AliHLTMUONRootifierComponent::~AliHLTMUONRootifierComponent()
49 {
50         ///
51         /// Default destructor.
52         ///
53 }
54
55
56 int AliHLTMUONRootifierComponent::DoInit(int /*argc*/, const char** /*argv*/)
57 {
58         ///
59         /// Inherited from AliHLTComponent.
60         /// Parses the command line parameters and initialises the component.
61         ///
62         
63         return 0;
64 }
65
66
67 int AliHLTMUONRootifierComponent::DoDeinit()
68 {
69         ///
70         /// Inherited from AliHLTComponent. Performs a cleanup of the component.
71         ///
72         
73         return 0;
74 }
75
76
77 const char* AliHLTMUONRootifierComponent::GetComponentID()
78 {
79         ///
80         /// Inherited from AliHLTComponent. Returns the component ID.
81         ///
82         
83         return "MUONRootifier";
84 }
85
86
87 AliHLTComponentDataType AliHLTMUONRootifierComponent::GetOutputDataType()
88 {
89         /// Inherited from AliHLTComponent. Returns kAliHLTMultipleDataType
90         /// refer to GetOutputDataTypes for all returned data types.
91         
92         return kAliHLTMultipleDataType;
93 }
94
95
96 int AliHLTMUONRootifierComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList)
97 {
98         /// Inherited from AliHLTComponent. Returns the output data types.
99         
100         tgtList.push_back(kAliHLTAnyDataType);
101         return 1;
102 }
103
104
105 void AliHLTMUONRootifierComponent::GetInputDataTypes(
106                 vector<AliHLTComponentDataType>& list
107         )
108 {
109         ///
110         /// Inherited from AliHLTProcessor. Returns the list of expected input data types.
111         ///
112         
113         list.push_back(kAliHLTAnyDataType);
114 }
115
116
117 void AliHLTMUONRootifierComponent::GetOutputDataSize(
118                 unsigned long& constBase, double& inputMultiplier
119         )
120 {
121         ///
122         /// Inherited from AliHLTComponent. Returns an estimate of the expected output data size.
123         ///
124         
125         constBase = 1024*1024;
126         inputMultiplier = 100;
127 }
128
129
130 AliHLTComponent* AliHLTMUONRootifierComponent::Spawn()
131 {
132         ///
133         /// Inherited from AliHLTComponent. Creates a new object instance.
134         ///
135         
136         return new AliHLTMUONRootifierComponent();
137 }
138
139
140 int AliHLTMUONRootifierComponent::DoEvent(
141                 const AliHLTComponentEventData& evtData,
142                 AliHLTComponentTriggerData& /*trigData*/
143         )
144 {
145         ///
146         /// Inherited from AliHLTProcessor. Processes the new event data.
147         ///
148         
149         AliHLTMUONEvent event(evtData.fEventID);
150
151         // First process the blocks of reconstructed hits and trigger records.
152         for (int i = 0; i < GetNumberOfInputBlocks(); i++)
153         {
154                 const AliHLTComponentBlockData* block = GetInputBlock(i);
155                 assert( block != NULL );
156                 if (block->fDataType == AliHLTMUONConstants::RecHitsBlockDataType())
157                 {
158                         AliHLTUInt8_t* ptr = reinterpret_cast<AliHLTUInt8_t*>(block->fPtr);
159                         ptr += block->fOffset;
160                         AliHLTMUONRecHitsBlockReader inblock(ptr, block->fSize);
161                         if (not inblock.BufferSizeOk())
162                         {
163                                 size_t headerSize = sizeof(AliHLTMUONRecHitsBlockReader::HeaderType);
164                                 if (block->fSize < headerSize)
165                                 {
166                                         HLTError("Received a reconstructed hits data block with a size of %d bytes,"
167                                                 " which is smaller than the minimum valid header size of %d bytes."
168                                                 " The block must be corrupt.",
169                                                 block->fSize, headerSize
170                                         );
171                                         continue;
172                                 }
173                                 
174                                 size_t expectedWidth = sizeof(AliHLTMUONRecHitsBlockReader::ElementType);
175                                 if (inblock.CommonBlockHeader().fRecordWidth != expectedWidth)
176                                 {
177                                         HLTError("Received a reconstructed hits data block with a record"
178                                                 " width of %d bytes, but the expected value is %d bytes."
179                                                 " The block might be corrupt.",
180                                                 block->fSize, headerSize
181                                         );
182                                         continue;
183                                 }
184                                 
185                                 HLTError("Received a reconstructed hits data block with a size of %d bytes,"
186                                         " but the block header claims the block should be %d bytes."
187                                         " The block might be corrupt.",
188                                         block->fSize, inblock.BytesUsed()
189                                 );
190                                 continue;
191                         }
192                         
193                         // Decode the source DDL from the specification bits.
194                         Int_t sourceDDL = -1;
195                         bool ddl[22];
196                         AliHLTMUONUtils::UnpackSpecBits(block->fSpecification, ddl);
197                         for (int k = 0; k < 22; k++)
198                         {
199                                 if (ddl[k])
200                                 {
201                                         if (sourceDDL == -1)
202                                         {
203                                                 sourceDDL = k+1;
204                                         }
205                                         else
206                                         {
207                                                 HLTWarning("The input data block %d contains"
208                                                         " data from multiple DDL sources.", i
209                                                 );
210                                         }
211                                 }
212                         }
213                         if (sourceDDL > 20)
214                         {
215                                 HLTWarning("The source DDL for input data block %d is %d."
216                                         " The expected range for the DDL is [1..20].",
217                                         i, sourceDDL
218                                 );
219                         }
220                         
221                         for (AliHLTUInt32_t n = 0; n < inblock.Nentries(); n++)
222                         {
223                                 const AliHLTMUONRecHitStruct& h = inblock[n];
224                                 //AliHLTMUONRecHit rh(h.fX, h.fY, h.fZ, sourceDDL);
225                                 //PushBack(&rh, "ROOTHITS", "MUON");
226                                 event.Add(new AliHLTMUONRecHit(h.fX, h.fY, h.fZ, sourceDDL));
227                         }
228                 }
229                 else if (block->fDataType == AliHLTMUONConstants::TriggerRecordsBlockDataType())
230                 {
231                         AliHLTUInt8_t* ptr = reinterpret_cast<AliHLTUInt8_t*>(block->fPtr);
232                         ptr += block->fOffset;
233                         AliHLTMUONTriggerRecordsBlockReader inblock(ptr, block->fSize);
234                         if (not inblock.BufferSizeOk())
235                         {
236                                 size_t headerSize = sizeof(AliHLTMUONTriggerRecordsBlockReader::HeaderType);
237                                 if (block->fSize < headerSize)
238                                 {
239                                         HLTError("Received a trigger records data block with a size of %d bytes,"
240                                                 " which is smaller than the minimum valid header size of %d bytes."
241                                                 " The block must be corrupt.",
242                                                 block->fSize, headerSize
243                                         );
244                                         continue;
245                                 }
246                                 
247                                 size_t expectedWidth = sizeof(AliHLTMUONTriggerRecordsBlockReader::ElementType);
248                                 if (inblock.CommonBlockHeader().fRecordWidth != expectedWidth)
249                                 {
250                                         HLTError("Received a trigger records data block with a record"
251                                                 " width of %d bytes, but the expected value is %d bytes."
252                                                 " The block might be corrupt.",
253                                                 block->fSize, headerSize
254                                         );
255                                         continue;
256                                 }
257                                 
258                                 HLTError("Received a trigger records data block with a size of %d bytes,"
259                                         " but the block header claims the block should be %d bytes."
260                                         " The block might be corrupt.",
261                                         block->fSize, inblock.BytesUsed()
262                                 );
263                                 continue;
264                         }
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                         }
286                         if (sourceDDL != -1 and (sourceDDL < 21 or sourceDDL > 22))
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++)
308                                         tr->SetHit(k+11, t.fHit[k].fX, t.fHit[k].fY, t.fHit[k].fZ);
309                                 event.Add(tr);
310                         }
311                 }
312                 else
313                 {
314                         // TODO: ignore for now, but should log an optional message.
315                 }
316         }
317         
318         // Now we can look for tracks to add. We needed the ROOT trigger records
319         // and reco hits created before we can create track objects.
320         for (int i = 0; i < GetNumberOfInputBlocks(); i++)
321         {
322                 const AliHLTComponentBlockData* block = GetInputBlock(i);
323                 assert( block != NULL );
324                 if (block->fDataType == AliHLTMUONConstants::MansoTracksBlockDataType())
325                 {
326                         AliHLTUInt8_t* ptr = reinterpret_cast<AliHLTUInt8_t*>(block->fPtr);
327                         ptr += block->fOffset;
328                         AliHLTMUONMansoTracksBlockReader inblock(ptr, block->fSize);
329                         if (not inblock.BufferSizeOk())
330                         {
331                                 size_t headerSize = sizeof(AliHLTMUONMansoTracksBlockReader::HeaderType);
332                                 if (block->fSize < headerSize)
333                                 {
334                                         HLTError("Received a Manso tracks data block with a size of %d bytes,"
335                                                 " which is smaller than the minimum valid header size of %d bytes."
336                                                 " The block must be corrupt.",
337                                                 block->fSize, headerSize
338                                         );
339                                         continue;
340                                 }
341                                 
342                                 size_t expectedWidth = sizeof(AliHLTMUONMansoTracksBlockReader::ElementType);
343                                 if (inblock.CommonBlockHeader().fRecordWidth != expectedWidth)
344                                 {
345                                         HLTError("Received a Manso tracks data block with a record"
346                                                 " width of %d bytes, but the expected value is %d bytes."
347                                                 " The block might be corrupt.",
348                                                 block->fSize, headerSize
349                                         );
350                                         continue;
351                                 }
352                                 
353                                 HLTError("Received a Manso tracks data block with a size of %d bytes,"
354                                         " but the block header claims the block should be %d bytes."
355                                         " The block might be corrupt.",
356                                         block->fSize, inblock.BytesUsed()
357                                 );
358                                 continue;
359                         }
360                         
361                         for (AliHLTUInt32_t n = 0; n < inblock.Nentries(); n++)
362                         {
363                                 const AliHLTMUONMansoTrackStruct& t = inblock[n];
364                                 
365                                 AliHLTMUONParticleSign sign;
366                                 bool hitset[4];
367                                 AliHLTMUONUtils::UnpackMansoTrackFlags(
368                                                 t.fFlags, sign, hitset
369                                         );
370                                 
371                                 // Try find the trigger record in 'event'.
372                                 const AliHLTMUONTriggerRecord* trigrec = NULL;
373                                 for (Int_t k = 0; k < event.Array().GetEntriesFast(); k++)
374                                 {
375                                         if (event.Array()[k]->IsA() != AliHLTMUONTriggerRecord::Class())
376                                                 continue;
377                                         const AliHLTMUONTriggerRecord* tk =
378                                                 static_cast<const AliHLTMUONTriggerRecord*>(event.Array()[k]);
379                                         if (tk->Id() == t.fTrigRec)
380                                         {
381                                                 trigrec = tk;
382                                                 break;
383                                         }
384                                 }
385                                 
386                                 // Now try find the hits in 'event'.
387                                 // If they cannot be found then create new ones.
388                                 const AliHLTMUONRecHit* hit7 = NULL;
389                                 const AliHLTMUONRecHit* hit8 = NULL;
390                                 const AliHLTMUONRecHit* hit9 = NULL;
391                                 const AliHLTMUONRecHit* hit10 = NULL;
392                                 for (Int_t k = 0; k < event.Array().GetEntriesFast(); k++)
393                                 {
394                                         if (event.Array()[k]->IsA() != AliHLTMUONRecHit::Class())
395                                                 continue;
396                                         const AliHLTMUONRecHit* h =
397                                                 static_cast<const AliHLTMUONRecHit*>(event.Array()[k]);
398                                         
399                                         if (hitset[0] and h->X() == t.fHit[0].fX and h->Y() == t.fHit[0].fY
400                                             and h->Z() == t.fHit[0].fZ)
401                                         {
402                                                 hit7 = h;
403                                         }
404                                         if (hitset[1] and h->X() == t.fHit[1].fX and h->Y() == t.fHit[1].fY
405                                             and h->Z() == t.fHit[1].fZ)
406                                         {
407                                                 hit8 = h;
408                                         }
409                                         if (hitset[2] and h->X() == t.fHit[2].fX and h->Y() == t.fHit[2].fY
410                                             and h->Z() == t.fHit[2].fZ)
411                                         {
412                                                 hit9 = h;
413                                         }
414                                         if (hitset[3] and h->X() == t.fHit[3].fX and h->Y() == t.fHit[3].fY
415                                             and h->Z() == t.fHit[3].fZ)
416                                         {
417                                                 hit10 = h;
418                                         }
419                                 }
420                                 AliHLTMUONRecHit* newhit;
421                                 if (hitset[0] and hit7 == NULL)
422                                 {
423                                         newhit = new AliHLTMUONRecHit(t.fHit[0].fX, t.fHit[0].fY, t.fHit[0].fZ);
424                                         event.Add(newhit);
425                                         hit7 = newhit;
426                                 }
427                                 if (hitset[1] and hit8 == NULL)
428                                 {
429                                         newhit = new AliHLTMUONRecHit(t.fHit[1].fX, t.fHit[1].fY, t.fHit[1].fZ);
430                                         event.Add(newhit);
431                                         hit8 = newhit;
432                                 }
433                                 if (hitset[2] and hit9 == NULL)
434                                 {
435                                         newhit = new AliHLTMUONRecHit(t.fHit[2].fX, t.fHit[2].fY, t.fHit[2].fZ);
436                                         event.Add(newhit);
437                                         hit9 = newhit;
438                                 }
439                                 if (hitset[3] and hit10 == NULL)
440                                 {
441                                         newhit = new AliHLTMUONRecHit(t.fHit[3].fX, t.fHit[3].fY, t.fHit[3].fZ);
442                                         event.Add(newhit);
443                                         hit10 = newhit;
444                                 }
445                         
446                                 AliHLTMUONMansoTrack* tr = new AliHLTMUONMansoTrack(
447                                                 t.fId, sign, t.fPx, t.fPy, t.fPz, t.fChi2,
448                                                 trigrec, hit7, hit8, hit9, hit10
449                                         );
450                                 event.Add(tr);
451                         }
452                 }
453                 else
454                 {
455                         // TODO: ignore for now, but should log an optional message.
456                 }
457         }
458         
459         PushBack(&event, "ROOTEVNT", "MUON");
460         
461         return 0;
462 }
463
464
465 void AliHLTMUONEvent::Print(Option_t* option) const
466 {
467         ///
468         /// Inherited from TObject. Prints the contents of the event objects in fArray.
469         ///
470         
471         cout << "################## EVENT: " << fEventId << " ##################" << endl;
472         for (Int_t i = 0; i < fArray.GetEntriesFast(); i++)
473                 if (fArray[i] != NULL) fArray[i]->Print(option);
474 }
475