cf544dae1711f9ded1047bc980901e4c03529dee
[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 "TObjArray.h"
34 #include <cassert>
35
36 namespace
37 {
38         // The global object used for automatic component registration.
39         // Note DO NOT use this component for calculation!
40         AliHLTMUONRootifierComponent gAliHLTMUONRootifierComponent;
41 }
42
43 ClassImp(AliHLTMUONEvent);
44 ClassImp(AliHLTMUONRootifierComponent);
45
46
47 AliHLTMUONRootifierComponent::AliHLTMUONRootifierComponent() :
48         AliHLTProcessor()
49 {
50 }
51
52
53 AliHLTMUONRootifierComponent::~AliHLTMUONRootifierComponent()
54 {
55 }
56
57
58 int AliHLTMUONRootifierComponent::DoInit(int argc, const char** argv)
59 {
60         return 0;
61 }
62
63
64 int AliHLTMUONRootifierComponent::DoDeinit()
65 {
66         return 0;
67 }
68
69
70 const char* AliHLTMUONRootifierComponent::GetComponentID()
71 {
72         return "MUONRootifier";
73 }
74
75
76 AliHLTComponentDataType AliHLTMUONRootifierComponent::GetOutputDataType()
77 {
78         return kAliHLTAnyDataType;
79 }
80
81
82 void AliHLTMUONRootifierComponent::GetInputDataTypes(
83                 vector<AliHLTComponentDataType>& list
84         )
85 {
86         list.push_back(kAliHLTAnyDataType);
87 }
88
89
90 void AliHLTMUONRootifierComponent::GetOutputDataSize(
91                 unsigned long& constBase, double& inputMultiplier
92         )
93 {
94         constBase = 1024*1024;
95         inputMultiplier = 100;
96 }
97
98
99 AliHLTComponent* AliHLTMUONRootifierComponent::Spawn()
100 {
101         return new AliHLTMUONRootifierComponent();
102 }
103
104
105 int AliHLTMUONRootifierComponent::DoEvent(
106                 const AliHLTComponentEventData& evtData,
107                 AliHLTComponentTriggerData& trigData
108         )
109 {
110         AliHLTMUONEvent event(evtData.fEventID);
111
112         // First process the blocks of reconstructed hits and trigger records.
113         for (int i = 0; i < GetNumberOfInputBlocks(); i++)
114         {
115                 const AliHLTComponentBlockData* block = GetInputBlock(i);
116                 assert( block != NULL );
117                 if (block->fDataType == AliHLTMUONConstants::RecHitsBlockDataType())
118                 {
119                         AliHLTUInt8_t* ptr = reinterpret_cast<AliHLTUInt8_t*>(block->fPtr);
120                         ptr += block->fOffset;
121                         AliHLTMUONRecHitsBlockReader inblock(ptr, block->fSize);
122                         if (not inblock.BufferSizeOk())
123                         {
124                                 size_t headerSize = sizeof(AliHLTMUONRecHitsBlockReader::HeaderType);
125                                 if (block->fSize < headerSize)
126                                 {
127                                         HLTError("Received a reconstructed hits data block with a size of %d bytes,"
128                                                 " which is smaller than the minimum valid header size of %d bytes."
129                                                 " The block must be corrupt.",
130                                                 block->fSize, headerSize
131                                         );
132                                         continue;
133                                 }
134                                 
135                                 size_t expectedWidth = sizeof(AliHLTMUONRecHitsBlockReader::ElementType);
136                                 if (inblock.CommonBlockHeader().fRecordWidth != expectedWidth)
137                                 {
138                                         HLTError("Received a reconstructed hits data block with a record"
139                                                 " width of %d bytes, but the expected value is %d bytes."
140                                                 " The block might be corrupt.",
141                                                 block->fSize, headerSize
142                                         );
143                                         continue;
144                                 }
145                                 
146                                 HLTError("Received a reconstructed hits data block with a size of %d bytes,"
147                                         " but the block header claims the block should be %d bytes."
148                                         " The block might be corrupt.",
149                                         block->fSize, inblock.BytesUsed()
150                                 );
151                                 continue;
152                         }
153                         
154                         // Decode the source DDL from the specification bits.
155                         Int_t sourceDDL = -1;
156                         bool ddl[22];
157                         AliHLTMUONUtils::UnpackSpecBits(block->fSpecification, ddl);
158                         for (int k = 0; k < 22; k++)
159                         {
160                                 if (ddl[k])
161                                 {
162                                         if (sourceDDL == -1)
163                                         {
164                                                 sourceDDL = k+1;
165                                         }
166                                         else
167                                         {
168                                                 HLTWarning("The input data block %d contains"
169                                                         " data from multiple DDL sources.", i
170                                                 );
171                                         }
172                                 }
173                         }
174                         if (sourceDDL > 20)
175                         {
176                                 HLTWarning("The source DDL for input data block %d is %d."
177                                         " The expected range for the DDL is [1..20].",
178                                         i, sourceDDL
179                                 );
180                         }
181                         
182                         for (AliHLTUInt32_t n = 0; n < inblock.Nentries(); n++)
183                         {
184                                 const AliHLTMUONRecHitStruct& h = inblock[n];
185                                 //AliHLTMUONRecHit rh(h.fX, h.fY, h.fZ, sourceDDL);
186                                 //PushBack(&rh, "ROOTHITS", "MUON");
187                                 event.Add(new AliHLTMUONRecHit(h.fX, h.fY, h.fZ, sourceDDL));
188                         }
189                 }
190                 else if (block->fDataType == AliHLTMUONConstants::TriggerRecordsBlockDataType())
191                 {
192                         AliHLTUInt8_t* ptr = reinterpret_cast<AliHLTUInt8_t*>(block->fPtr);
193                         ptr += block->fOffset;
194                         AliHLTMUONTriggerRecordsBlockReader inblock(ptr, block->fSize);
195                         if (not inblock.BufferSizeOk())
196                         {
197                                 size_t headerSize = sizeof(AliHLTMUONTriggerRecordsBlockReader::HeaderType);
198                                 if (block->fSize < headerSize)
199                                 {
200                                         HLTError("Received a trigger records data block with a size of %d bytes,"
201                                                 " which is smaller than the minimum valid header size of %d bytes."
202                                                 " The block must be corrupt.",
203                                                 block->fSize, headerSize
204                                         );
205                                         continue;
206                                 }
207                                 
208                                 size_t expectedWidth = sizeof(AliHLTMUONTriggerRecordsBlockReader::ElementType);
209                                 if (inblock.CommonBlockHeader().fRecordWidth != expectedWidth)
210                                 {
211                                         HLTError("Received a trigger records data block with a record"
212                                                 " width of %d bytes, but the expected value is %d bytes."
213                                                 " The block might be corrupt.",
214                                                 block->fSize, headerSize
215                                         );
216                                         continue;
217                                 }
218                                 
219                                 HLTError("Received a trigger records data block with a size of %d bytes,"
220                                         " but the block header claims the block should be %d bytes."
221                                         " The block might be corrupt.",
222                                         block->fSize, inblock.BytesUsed()
223                                 );
224                                 continue;
225                         }
226                         
227                         // Decode the source DDL from the specification bits.
228                         Int_t sourceDDL = -1;
229                         bool ddl[22];
230                         AliHLTMUONUtils::UnpackSpecBits(block->fSpecification, ddl);
231                         for (int k = 0; k < 22; k++)
232                         {
233                                 if (ddl[k])
234                                 {
235                                         if (sourceDDL == -1)
236                                         {
237                                                 sourceDDL = k+1;
238                                         }
239                                         else
240                                         {
241                                                 HLTWarning("The input data block %d contains"
242                                                         " data from multiple DDL sources.", i
243                                                 );
244                                         }
245                                 }
246                         }
247                         if (sourceDDL < 21 or sourceDDL > 22)
248                         {
249                                 HLTWarning("The source DDL for input data block %d is %d."
250                                         " The expected range for the DDL is [21..22].",
251                                         i, sourceDDL
252                                 );
253                         }
254                         
255                         for (AliHLTUInt32_t n = 0; n < inblock.Nentries(); n++)
256                         {
257                                 const AliHLTMUONTriggerRecordStruct& t = inblock[n];
258                                 
259                                 AliHLTMUONParticleSign sign;
260                                 bool hitset[4];
261                                 AliHLTMUONUtils::UnpackTriggerRecordFlags(
262                                                 t.fFlags, sign, hitset
263                                         );
264                         
265                                 AliHLTMUONTriggerRecord* tr = new AliHLTMUONTriggerRecord(
266                                                 t.fId, sign, t.fPx, t.fPy, t.fPz, sourceDDL
267                                         );
268                                 for (int k = 0; k < 4; k++)
269                                         tr->SetHit(k+11, t.fHit[k].fX, t.fHit[k].fY, t.fHit[k].fZ);
270                                 event.Add(tr);
271                         }
272                 }
273                 else
274                 {
275                         // TODO: ignore for now, but should log an optional message.
276                 }
277         }
278         
279         // Now we can look for tracks to add. We needed the ROOT trigger records
280         // and reco hits created before we can create track objects.
281         for (int i = 0; i < GetNumberOfInputBlocks(); i++)
282         {
283                 const AliHLTComponentBlockData* block = GetInputBlock(i);
284                 assert( block != NULL );
285                 if (block->fDataType == AliHLTMUONConstants::MansoTracksBlockDataType())
286                 {
287                         AliHLTUInt8_t* ptr = reinterpret_cast<AliHLTUInt8_t*>(block->fPtr);
288                         ptr += block->fOffset;
289                         AliHLTMUONMansoTracksBlockReader inblock(ptr, block->fSize);
290                         if (not inblock.BufferSizeOk())
291                         {
292                                 size_t headerSize = sizeof(AliHLTMUONMansoTracksBlockReader::HeaderType);
293                                 if (block->fSize < headerSize)
294                                 {
295                                         HLTError("Received a Manso tracks data block with a size of %d bytes,"
296                                                 " which is smaller than the minimum valid header size of %d bytes."
297                                                 " The block must be corrupt.",
298                                                 block->fSize, headerSize
299                                         );
300                                         continue;
301                                 }
302                                 
303                                 size_t expectedWidth = sizeof(AliHLTMUONMansoTracksBlockReader::ElementType);
304                                 if (inblock.CommonBlockHeader().fRecordWidth != expectedWidth)
305                                 {
306                                         HLTError("Received a Manso tracks data block with a record"
307                                                 " width of %d bytes, but the expected value is %d bytes."
308                                                 " The block might be corrupt.",
309                                                 block->fSize, headerSize
310                                         );
311                                         continue;
312                                 }
313                                 
314                                 HLTError("Received a Manso tracks data block with a size of %d bytes,"
315                                         " but the block header claims the block should be %d bytes."
316                                         " The block might be corrupt.",
317                                         block->fSize, inblock.BytesUsed()
318                                 );
319                                 continue;
320                         }
321                         
322                         for (AliHLTUInt32_t n = 0; n < inblock.Nentries(); n++)
323                         {
324                                 const AliHLTMUONMansoTrackStruct& t = inblock[n];
325                                 
326                                 AliHLTMUONParticleSign sign;
327                                 bool hitset[4];
328                                 AliHLTMUONUtils::UnpackMansoTrackFlags(
329                                                 t.fFlags, sign, hitset
330                                         );
331                                 
332                                 // Try find the trigger record in 'event'.
333                                 const AliHLTMUONTriggerRecord* trigrec = NULL;
334                                 for (Int_t k = 0; k < event.Array().GetEntriesFast(); k++)
335                                 {
336                                         if (event.Array()[k]->IsA() != AliHLTMUONTriggerRecord::Class())
337                                                 continue;
338                                         const AliHLTMUONTriggerRecord* tk =
339                                                 static_cast<const AliHLTMUONTriggerRecord*>(event.Array()[k]);
340                                         if (tk->Id() == t.fTrigRec)
341                                         {
342                                                 trigrec = tk;
343                                                 break;
344                                         }
345                                 }
346                                 
347                                 // Now try find the hits in 'event'.
348                                 // If they cannot be found then create new ones.
349                                 const AliHLTMUONRecHit* hit7 = NULL;
350                                 const AliHLTMUONRecHit* hit8 = NULL;
351                                 const AliHLTMUONRecHit* hit9 = NULL;
352                                 const AliHLTMUONRecHit* hit10 = NULL;
353                                 for (Int_t k = 0; k < event.Array().GetEntriesFast(); k++)
354                                 {
355                                         if (event.Array()[k]->IsA() != AliHLTMUONRecHit::Class())
356                                                 continue;
357                                         const AliHLTMUONRecHit* h =
358                                                 static_cast<const AliHLTMUONRecHit*>(event.Array()[k]);
359                                         
360                                         if (hitset[0] and h->X() == t.fHit[0].fX and h->Y() == t.fHit[0].fY
361                                             and h->Z() == t.fHit[0].fZ)
362                                         {
363                                                 hit7 = h;
364                                         }
365                                         if (hitset[1] and h->X() == t.fHit[1].fX and h->Y() == t.fHit[1].fY
366                                             and h->Z() == t.fHit[1].fZ)
367                                         {
368                                                 hit8 = h;
369                                         }
370                                         if (hitset[2] and h->X() == t.fHit[2].fX and h->Y() == t.fHit[2].fY
371                                             and h->Z() == t.fHit[2].fZ)
372                                         {
373                                                 hit9 = h;
374                                         }
375                                         if (hitset[3] and h->X() == t.fHit[3].fX and h->Y() == t.fHit[3].fY
376                                             and h->Z() == t.fHit[3].fZ)
377                                         {
378                                                 hit10 = h;
379                                         }
380                                 }
381                                 AliHLTMUONRecHit* newhit;
382                                 if (hitset[0] and hit7 == NULL)
383                                 {
384                                         newhit = new AliHLTMUONRecHit(t.fHit[0].fX, t.fHit[0].fY, t.fHit[0].fZ);
385                                         event.Add(newhit);
386                                         hit7 = newhit;
387                                 }
388                                 if (hitset[1] and hit8 == NULL)
389                                 {
390                                         newhit = new AliHLTMUONRecHit(t.fHit[1].fX, t.fHit[1].fY, t.fHit[1].fZ);
391                                         event.Add(newhit);
392                                         hit8 = newhit;
393                                 }
394                                 if (hitset[2] and hit9 == NULL)
395                                 {
396                                         newhit = new AliHLTMUONRecHit(t.fHit[2].fX, t.fHit[2].fY, t.fHit[2].fZ);
397                                         event.Add(newhit);
398                                         hit9 = newhit;
399                                 }
400                                 if (hitset[3] and hit10 == NULL)
401                                 {
402                                         newhit = new AliHLTMUONRecHit(t.fHit[3].fX, t.fHit[3].fY, t.fHit[3].fZ);
403                                         event.Add(newhit);
404                                         hit10 = newhit;
405                                 }
406                         
407                                 AliHLTMUONMansoTrack* tr = new AliHLTMUONMansoTrack(
408                                                 t.fId, sign, t.fPx, t.fPy, t.fPz, t.fChi2,
409                                                 trigrec, hit7, hit8, hit9, hit10
410                                         );
411                                 event.Add(tr);
412                         }
413                 }
414                 else
415                 {
416                         // TODO: ignore for now, but should log an optional message.
417                 }
418         }
419         
420         PushBack(&event, "ROOTEVNT", "MUON");
421         
422         return 0;
423 }