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