Changes to remove overlaps (M. Sitta)
[u/mrichter/AliRoot.git] / HLT / MUON / OfflineInterface / AliHLTMUONRootifierComponent.cxx
CommitLineData
9acda34c 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
cb35e21b 19///
20/// @file AliHLTMUONRootifierComponent.cxx
21/// @author Artur Szostak <artursz@iafrica.com>
22/// @date
23/// @brief Implementation of the AliHLTMUONRootifierComponent component.
24///
9acda34c 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"
9acda34c 33#include <cassert>
34
9acda34c 35ClassImp(AliHLTMUONEvent);
36ClassImp(AliHLTMUONRootifierComponent);
37
38
39AliHLTMUONRootifierComponent::AliHLTMUONRootifierComponent() :
40 AliHLTProcessor()
41{
6253e09b 42 ///
43 /// Default constructor.
44 ///
9acda34c 45}
46
47
48AliHLTMUONRootifierComponent::~AliHLTMUONRootifierComponent()
49{
6253e09b 50 ///
51 /// Default destructor.
52 ///
9acda34c 53}
54
55
6253e09b 56int AliHLTMUONRootifierComponent::DoInit(int /*argc*/, const char** /*argv*/)
9acda34c 57{
6253e09b 58 ///
59 /// Inherited from AliHLTComponent.
60 /// Parses the command line parameters and initialises the component.
61 ///
62
9acda34c 63 return 0;
64}
65
66
67int AliHLTMUONRootifierComponent::DoDeinit()
68{
6253e09b 69 ///
70 /// Inherited from AliHLTComponent. Performs a cleanup of the component.
71 ///
72
9acda34c 73 return 0;
74}
75
76
77const char* AliHLTMUONRootifierComponent::GetComponentID()
78{
6253e09b 79 ///
80 /// Inherited from AliHLTComponent. Returns the component ID.
81 ///
82
9acda34c 83 return "MUONRootifier";
84}
85
86
87AliHLTComponentDataType AliHLTMUONRootifierComponent::GetOutputDataType()
88{
bb14e9db 89 /// Inherited from AliHLTComponent. Returns kAliHLTMultipleDataType
90 /// refer to GetOutputDataTypes for all returned data types.
91
92 return kAliHLTMultipleDataType;
93}
94
95
96int AliHLTMUONRootifierComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList)
97{
98 /// Inherited from AliHLTComponent. Returns the output data types.
6253e09b 99
bb14e9db 100 tgtList.push_back(kAliHLTAnyDataType);
101 return 1;
9acda34c 102}
103
104
105void AliHLTMUONRootifierComponent::GetInputDataTypes(
106 vector<AliHLTComponentDataType>& list
107 )
108{
6253e09b 109 ///
110 /// Inherited from AliHLTProcessor. Returns the list of expected input data types.
111 ///
112
9acda34c 113 list.push_back(kAliHLTAnyDataType);
114}
115
116
117void AliHLTMUONRootifierComponent::GetOutputDataSize(
118 unsigned long& constBase, double& inputMultiplier
119 )
120{
6253e09b 121 ///
122 /// Inherited from AliHLTComponent. Returns an estimate of the expected output data size.
123 ///
124
477135e2 125 constBase = 1024*1024;
126 inputMultiplier = 100;
9acda34c 127}
128
129
130AliHLTComponent* AliHLTMUONRootifierComponent::Spawn()
131{
6253e09b 132 ///
133 /// Inherited from AliHLTComponent. Creates a new object instance.
134 ///
135
9acda34c 136 return new AliHLTMUONRootifierComponent();
137}
138
139
140int AliHLTMUONRootifierComponent::DoEvent(
141 const AliHLTComponentEventData& evtData,
6253e09b 142 AliHLTComponentTriggerData& /*trigData*/
9acda34c 143 )
144{
6253e09b 145 ///
146 /// Inherited from AliHLTProcessor. Processes the new event data.
147 ///
148
9acda34c 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 }
bb14e9db 286 if (sourceDDL != -1 and (sourceDDL < 21 or sourceDDL > 22))
9acda34c 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}
6253e09b 463
464
465void 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