]>
Commit | Line | Data |
---|---|---|
b92524d0 | 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 | * Indranil Das <indra.das@saha.ac.in> * | |
8 | * * | |
9 | * Permission to use, copy, modify and distribute this software and its * | |
10 | * documentation strictly for non-commercial purposes is hereby granted * | |
11 | * without fee, provided that the above copyright notice appears in all * | |
12 | * copies and that both the copyright notice and this permission notice * | |
13 | * appear in the supporting documentation. The authors make no claims * | |
14 | * about the suitability of this software for any purpose. It is * | |
15 | * provided "as is" without express or implied warranty. * | |
16 | **************************************************************************/ | |
17 | ||
18 | /* $Id$ */ | |
19 | ||
20 | /** | |
21 | * @file AliHLTMUONMansoTrackerFSMComponent.cxx | |
22 | * @author Artur Szostak <artursz@iafrica.com>, | |
23 | * Indranil Das <indra.das@saha.ac.in> | |
24 | * @date | |
25 | * @brief Implementation of AliHLTMUONMansoTrackerFSMComponent class. | |
26 | */ | |
27 | ||
28 | #include "AliHLTMUONMansoTrackerFSMComponent.h" | |
29 | #include "AliHLTMUONConstants.h" | |
30 | #include "AliHLTMUONUtils.h" | |
31 | #include "AliHLTMUONMansoTrackerFSM.h" | |
32 | #include "AliHLTMUONDataBlockReader.h" | |
33 | #include "AliHLTMUONDataBlockWriter.h" | |
34 | #include <cstdlib> | |
d42549e3 | 35 | #include <cstring> |
b92524d0 | 36 | #include <cerrno> |
37 | ||
38 | namespace | |
39 | { | |
40 | // The global object used for automatic component registration. | |
41 | // Note DO NOT use this component for calculation! | |
42 | AliHLTMUONMansoTrackerFSMComponent gAliHLTMUONMansoTrackerFSMComponent; | |
43 | ||
44 | } // end of namespace | |
45 | ||
46 | ||
47 | ClassImp(AliHLTMUONMansoTrackerFSMComponent); | |
48 | ||
49 | ||
50 | AliHLTMUONMansoTrackerFSMComponent::AliHLTMUONMansoTrackerFSMComponent() : | |
51 | AliHLTProcessor(), | |
52 | AliHLTMUONMansoTrackerFSMCallback(), | |
53 | fTracker(NULL), | |
54 | fTrackCount(0), | |
d42549e3 | 55 | fBlock(NULL), |
56 | fWarnForUnexpecedBlock(false) | |
b92524d0 | 57 | { |
58 | } | |
59 | ||
60 | ||
61 | AliHLTMUONMansoTrackerFSMComponent::~AliHLTMUONMansoTrackerFSMComponent() | |
62 | { | |
63 | assert( fTracker == NULL ); | |
64 | } | |
65 | ||
66 | ||
67 | const char* AliHLTMUONMansoTrackerFSMComponent::GetComponentID() | |
68 | { | |
69 | return AliHLTMUONConstants::MansoTrackerFSMId(); | |
70 | } | |
71 | ||
72 | ||
73 | void AliHLTMUONMansoTrackerFSMComponent::GetInputDataTypes( | |
74 | vector<AliHLTComponentDataType>& list | |
75 | ) | |
76 | { | |
77 | assert( list.empty() ); | |
78 | list.push_back( AliHLTMUONConstants::TriggerRecordsBlockDataType() ); | |
79 | list.push_back( AliHLTMUONConstants::RecHitsBlockDataType() ); | |
80 | } | |
81 | ||
82 | ||
83 | AliHLTComponentDataType AliHLTMUONMansoTrackerFSMComponent::GetOutputDataType() | |
84 | { | |
85 | return AliHLTMUONConstants::MansoTracksBlockDataType(); | |
86 | } | |
87 | ||
88 | ||
89 | void AliHLTMUONMansoTrackerFSMComponent::GetOutputDataSize( | |
90 | unsigned long& constBase, double& inputMultiplier | |
91 | ) | |
92 | { | |
93 | constBase = sizeof(AliHLTMUONMansoTracksBlockStruct); | |
94 | inputMultiplier = 1; | |
95 | } | |
96 | ||
97 | ||
98 | AliHLTComponent* AliHLTMUONMansoTrackerFSMComponent::Spawn() | |
99 | { | |
100 | return new AliHLTMUONMansoTrackerFSMComponent; | |
101 | } | |
102 | ||
103 | ||
104 | int AliHLTMUONMansoTrackerFSMComponent::DoInit(int argc, const char** argv) | |
105 | { | |
106 | fTracker = new AliHLTMUONMansoTrackerFSM(); | |
107 | fTracker->SetCallback(this); | |
d42549e3 | 108 | |
109 | fWarnForUnexpecedBlock = false; | |
110 | ||
111 | for (int i = 0; i < argc; i++) | |
112 | { | |
113 | if (strcmp(argv[i], "-warn_on_unexpected_block") == 0) | |
114 | fWarnForUnexpecedBlock = true; | |
115 | } | |
116 | ||
b92524d0 | 117 | return 0; |
118 | } | |
119 | ||
120 | ||
121 | int AliHLTMUONMansoTrackerFSMComponent::DoDeinit() | |
122 | { | |
123 | if (fTracker != NULL) | |
124 | { | |
125 | delete fTracker; | |
126 | fTracker = NULL; | |
127 | } | |
128 | return 0; | |
129 | } | |
130 | ||
131 | ||
132 | int AliHLTMUONMansoTrackerFSMComponent::DoEvent( | |
133 | const AliHLTComponentEventData& evtData, | |
134 | const AliHLTComponentBlockData* blocks, | |
135 | AliHLTComponentTriggerData& trigData, | |
136 | AliHLTUInt8_t* outputPtr, | |
137 | AliHLTUInt32_t& size, | |
138 | std::vector<AliHLTComponentBlockData>& outputBlocks | |
139 | ) | |
140 | { | |
141 | Reset(); | |
142 | AliHLTUInt32_t specification = 0; // Contains the output data block spec bits. | |
143 | ||
144 | AliHLTMUONMansoTracksBlockWriter block(outputPtr, size); | |
145 | fBlock = █ | |
146 | ||
147 | if (not block.InitCommonHeader()) | |
148 | { | |
149 | Logging(kHLTLogError, | |
150 | "AliHLTMUONMansoTrackerFSMComponent::DoEvent", | |
151 | "Buffer overflow", | |
152 | "The buffer is only %d bytes in size. We need a minimum of %d bytes.", | |
153 | size, sizeof(AliHLTMUONMansoTracksBlockWriter::HeaderType) | |
154 | ); | |
155 | size = 0; // Important to tell framework that nothing was generated. | |
156 | return ENOBUFS; | |
157 | } | |
158 | ||
159 | // Loop over all input blocks in the event and add the ones that contain | |
160 | // reconstructed hits into the hit buffers. The blocks containing trigger | |
161 | // records are ignored for now and will be processed later. | |
162 | for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++) | |
163 | { | |
164 | if (blocks[n].fDataType == AliHLTMUONConstants::RecHitsBlockDataType()) | |
165 | { | |
166 | specification |= blocks[n].fSpecification; | |
167 | ||
168 | AliHLTMUONRecHitsBlockReader inblock(blocks[n].fPtr, blocks[n].fSize); | |
169 | if (not inblock.BufferSizeOk()) | |
170 | { | |
d42549e3 | 171 | size_t headerSize = sizeof(AliHLTMUONRecHitsBlockReader::HeaderType); |
172 | if (blocks[n].fSize < headerSize) | |
173 | { | |
174 | HLTError("Received a reconstructed hits data block with a size of %d bytes," | |
175 | " which is smaller than the minimum valid header size of %d bytes." | |
176 | " The block must be corrupt.", | |
177 | blocks[n].fSize, headerSize | |
178 | ); | |
179 | continue; | |
180 | } | |
181 | ||
182 | size_t expectedWidth = sizeof(AliHLTMUONRecHitsBlockReader::ElementType); | |
183 | if (inblock.CommonBlockHeader().fRecordWidth != expectedWidth) | |
184 | { | |
185 | HLTError("Received a reconstructed hits data block with a record" | |
186 | " width of %d bytes, but the expected value is %d bytes." | |
187 | " The block might be corrupt.", | |
188 | blocks[n].fSize, headerSize | |
189 | ); | |
190 | continue; | |
191 | } | |
192 | ||
193 | HLTError("Received a reconstructed hits data block with a size of %d bytes," | |
194 | " but the block header claims the block should be %d bytes." | |
195 | " The block might be corrupt.", | |
196 | blocks[n].fSize, inblock.BytesUsed() | |
b92524d0 | 197 | ); |
198 | continue; | |
199 | } | |
200 | ||
4a9f11d4 | 201 | if (inblock.Nentries() != 0) |
202 | AddRecHits(blocks[n].fSpecification, inblock.GetArray(), inblock.Nentries()); | |
203 | else | |
204 | { | |
d42549e3 | 205 | Logging(kHLTLogDebug, |
4a9f11d4 | 206 | "AliHLTMUONMansoTrackerFSMComponent::DoEvent", |
207 | "Block empty", | |
208 | "Received a reconstructed hits data block which contains no entries." | |
209 | ); | |
210 | } | |
b92524d0 | 211 | } |
212 | else if (blocks[n].fDataType != AliHLTMUONConstants::TriggerRecordsBlockDataType()) | |
213 | { | |
214 | // Log a message indicating that we got a data block that we | |
215 | // do not know how to handle. | |
216 | char id[kAliHLTComponentDataTypefIDsize+1]; | |
217 | for (int i = 0; i < kAliHLTComponentDataTypefIDsize; i++) | |
218 | id[i] = blocks[n].fDataType.fID[i]; | |
219 | id[kAliHLTComponentDataTypefIDsize] = '\0'; | |
220 | char origin[kAliHLTComponentDataTypefOriginSize+1]; | |
221 | for (int i = 0; i < kAliHLTComponentDataTypefOriginSize; i++) | |
222 | origin[i] = blocks[n].fDataType.fOrigin[i]; | |
223 | origin[kAliHLTComponentDataTypefOriginSize] = '\0'; | |
224 | ||
d42549e3 | 225 | if (fWarnForUnexpecedBlock) |
226 | HLTWarning("Received a data block of a type we cannot handle: %s origin: %s", | |
227 | static_cast<char*>(id), static_cast<char*>(origin) | |
228 | ); | |
229 | else | |
230 | HLTDebug("Received a data block of a type we cannot handle: %s origin: %s", | |
231 | static_cast<char*>(id), static_cast<char*>(origin) | |
232 | ); | |
b92524d0 | 233 | } |
234 | } | |
235 | ||
236 | // Again loop over all input blocks in the event, but this time look for | |
237 | // the trigger record blocks and process these. | |
238 | for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++) | |
239 | { | |
240 | if (blocks[n].fDataType != AliHLTMUONConstants::TriggerRecordsBlockDataType()) | |
241 | continue; | |
242 | ||
243 | AliHLTMUONTriggerRecordsBlockReader inblock(blocks[n].fPtr, blocks[n].fSize); | |
244 | if (not inblock.BufferSizeOk()) | |
245 | { | |
d42549e3 | 246 | size_t headerSize = sizeof(AliHLTMUONTriggerRecordsBlockReader::HeaderType); |
247 | if (blocks[n].fSize < headerSize) | |
248 | { | |
249 | HLTError("Received a trigger records data block with a size of %d bytes," | |
250 | " which is smaller than the minimum valid header size of %d bytes." | |
251 | " The block must be corrupt.", | |
252 | blocks[n].fSize, headerSize | |
253 | ); | |
254 | continue; | |
255 | } | |
256 | ||
257 | size_t expectedWidth = sizeof(AliHLTMUONTriggerRecordsBlockReader::ElementType); | |
258 | if (inblock.CommonBlockHeader().fRecordWidth != expectedWidth) | |
259 | { | |
260 | HLTError("Received a trigger records data block with a record" | |
261 | " width of %d bytes, but the expected value is %d bytes." | |
262 | " The block might be corrupt.", | |
263 | blocks[n].fSize, headerSize | |
264 | ); | |
265 | continue; | |
266 | } | |
267 | ||
268 | HLTError("Received a trigger records data block with a size of %d bytes," | |
269 | " but the block header claims the block should be %d bytes." | |
270 | " The block might be corrupt.", | |
271 | blocks[n].fSize, inblock.BytesUsed() | |
b92524d0 | 272 | ); |
273 | continue; | |
274 | } | |
275 | DebugTrace("Processing a trigger block with " | |
276 | << inblock.Nentries() << " entries." | |
277 | ); | |
278 | ||
279 | specification |= blocks[n].fSpecification; | |
280 | ||
281 | for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++) | |
282 | { | |
283 | fTracker->FindTrack(inblock[i]); | |
284 | ||
285 | // Reset the tracker so that we do not double count tracks. | |
286 | fTracker->Reset(); | |
287 | } | |
288 | } | |
289 | ||
290 | AliHLTComponentBlockData bd; | |
291 | FillBlockData(bd); | |
292 | bd.fPtr = outputPtr; | |
293 | bd.fOffset = 0; | |
294 | bd.fSize = block.BytesUsed(); | |
295 | bd.fDataType = AliHLTMUONConstants::MansoTracksBlockDataType(); | |
296 | bd.fSpecification = specification; | |
297 | outputBlocks.push_back(bd); | |
298 | size = block.BytesUsed(); | |
299 | ||
300 | return 0; | |
301 | } | |
302 | ||
303 | ||
304 | void AliHLTMUONMansoTrackerFSMComponent::Reset() | |
305 | { | |
306 | DebugTrace("Resetting AliHLTMUONMansoTrackerFSMComponent."); | |
307 | ||
308 | //fTracker->Reset(); // Not necessary here because it is done after every FindTrack call. | |
309 | fTrackCount = 0; | |
310 | fBlock = NULL; // Do not delete. Already done implicitly at the end of DoEvent. | |
311 | for (int i = 0; i < 4; i++) | |
312 | { | |
313 | fRecHitBlock[i].erase(fRecHitBlock[i].begin(), fRecHitBlock[i].end()); | |
314 | } | |
315 | } | |
316 | ||
317 | ||
318 | void AliHLTMUONMansoTrackerFSMComponent::AddRecHits( | |
319 | AliHLTUInt32_t specification, | |
320 | const AliHLTMUONRecHitStruct* recHits, | |
321 | AliHLTUInt32_t count | |
322 | ) | |
323 | { | |
324 | DebugTrace("AliHLTMUONMansoTrackerFSMComponent::AddRecHits called with specification = 0x" | |
325 | << std::hex << specification << std::dec << " and count = " | |
326 | << count << " rec hits." | |
327 | ); | |
328 | ||
329 | AliHLTUInt8_t chamberMap[20] = { | |
330 | 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10 | |
331 | }; | |
332 | ||
333 | // Identify the chamber the rec hits came from using the specifications field. | |
334 | bool gotDataFromDDL[22]; | |
335 | AliHLTMUONUtils::UnpackSpecBits(specification, gotDataFromDDL); | |
336 | ||
337 | AliHLTInt8_t chamber = -1; | |
338 | for (int i = 0; i < 20; i++) | |
339 | { | |
340 | if (not gotDataFromDDL[i]) continue; | |
341 | if (7 <= chamberMap[i] and chamberMap[i] <= 10) | |
342 | { | |
343 | if (chamber != -1 and chamber != chamberMap[i]) | |
344 | { | |
345 | Logging(kHLTLogError, | |
346 | "AliHLTMUONMansoTrackerFSMComponent::AddRecHits", | |
347 | "Invalid block", | |
348 | "Received a data block with data from multiple chambers." | |
349 | " This component cannot handle such a case." | |
350 | ); | |
351 | return; | |
352 | } | |
353 | else | |
354 | chamber = chamberMap[i]; | |
355 | } | |
356 | else | |
357 | { | |
358 | Logging(kHLTLogError, | |
359 | "AliHLTMUONMansoTrackerFSMComponent::AddRecHits", | |
360 | "Invalid chamber", | |
361 | "Received a data block with data from chamber %d" | |
362 | " which is outside the expected range: [7..10].", | |
363 | chamberMap[i] | |
364 | ); | |
365 | return; | |
366 | } | |
367 | } | |
368 | ||
369 | // Make sure we got one chamber number. | |
370 | if (chamber < 7 or 10 < chamber) | |
371 | { | |
372 | Logging(kHLTLogError, | |
373 | "AliHLTMUONMansoTrackerFSMComponent::AddRecHits", | |
374 | "Invalid block", | |
375 | "Received a reconstructed hit data block with a null specification." | |
376 | " Cannot know which chamber the data comes from." | |
377 | ); | |
378 | return; | |
379 | } | |
380 | ||
381 | DebugTrace("Added " << count << " reconstructed hits from chamber " | |
d42549e3 | 382 | << (int)chamber << " to the internal arrays." |
383 | ); | |
b92524d0 | 384 | |
385 | RecHitBlockInfo info; | |
386 | info.fCount = count; | |
387 | info.fData = recHits; | |
388 | fRecHitBlock[chamber-7].push_back(info); | |
389 | } | |
390 | ||
391 | ||
392 | void AliHLTMUONMansoTrackerFSMComponent::RequestClusters( | |
393 | AliHLTMUONMansoTrackerFSM* tracker, | |
f1169efa | 394 | AliHLTFloat32_t left, AliHLTFloat32_t right, |
395 | AliHLTFloat32_t bottom, AliHLTFloat32_t top, | |
b92524d0 | 396 | AliHLTMUONChamberName chamber, const void* tag |
397 | ) | |
398 | { | |
399 | DebugTrace("AliHLTMUONMansoTracker::RequestClusters(chamber = " << chamber << ")"); | |
400 | void* ctag = const_cast<void*>(tag); | |
401 | int chNo = -1; | |
402 | std::vector<RecHitBlockInfo>* recHitsBlock = NULL; | |
403 | switch (chamber) | |
404 | { | |
405 | case kChamber7: | |
406 | recHitsBlock = &fRecHitBlock[0]; | |
407 | chNo = 7; | |
408 | break; | |
409 | ||
410 | case kChamber8: | |
411 | recHitsBlock = &fRecHitBlock[1]; | |
412 | chNo = 8; | |
413 | break; | |
414 | ||
415 | case kChamber9: | |
416 | recHitsBlock = &fRecHitBlock[2]; | |
417 | chNo = 9; | |
418 | break; | |
419 | ||
420 | case kChamber10: | |
421 | recHitsBlock = &fRecHitBlock[3]; | |
422 | chNo = 10; | |
423 | break; | |
424 | ||
425 | default: return; | |
426 | } | |
427 | ||
428 | DebugTrace("Returning requested hits for chamber " << chNo << ":"); | |
429 | for (AliHLTUInt32_t i = 0; i < recHitsBlock->size(); i++) | |
f1169efa | 430 | for (AliHLTUInt32_t j = 0; j < (*recHitsBlock)[i].fCount; j++) |
b92524d0 | 431 | { |
f1169efa | 432 | const AliHLTMUONRecHitStruct* hit = &((*recHitsBlock)[i].fData[j]); |
433 | if (left < hit->fX and hit->fX < right and bottom < hit->fY and hit->fY < top) | |
434 | tracker->ReturnClusters(ctag, hit, 1); | |
b92524d0 | 435 | } |
436 | DebugTrace("Done returning hits from chamber " << chNo << "."); | |
437 | tracker->EndOfClusters(ctag); | |
438 | } | |
439 | ||
440 | ||
441 | void AliHLTMUONMansoTrackerFSMComponent::EndOfClusterRequests( | |
442 | AliHLTMUONMansoTrackerFSM* tracker | |
443 | ) | |
444 | { | |
445 | DebugTrace("End of cluster requests."); | |
446 | } | |
447 | ||
448 | ||
449 | void AliHLTMUONMansoTrackerFSMComponent::FoundTrack(AliHLTMUONMansoTrackerFSM* tracker) | |
450 | { | |
451 | DebugTrace("AliHLTMUONMansoTrackerFSMComponent::FoundTrack()"); | |
452 | ||
453 | AliHLTMUONMansoTracksBlockWriter* block = | |
454 | reinterpret_cast<AliHLTMUONMansoTracksBlockWriter*>(fBlock); | |
455 | ||
456 | AliHLTMUONMansoTrackStruct* track = block->AddEntry(); | |
457 | if (track == NULL) | |
458 | { | |
459 | Logging(kHLTLogError, | |
460 | "AliHLTMUONMansoTrackerFSMComponent::FoundTrack", | |
461 | "Buffer overflow", | |
462 | "We have overflowed the output buffer for Manso track data." | |
463 | " The output buffer size is only %d bytes.", | |
464 | block->BufferSize() | |
465 | ); | |
466 | return; | |
467 | } | |
468 | ||
469 | fTrackCount++; | |
470 | tracker->FillTrackData(*track); | |
471 | DebugTrace("\tTrack data = " << *track); | |
472 | } | |
473 | ||
474 | ||
475 | void AliHLTMUONMansoTrackerFSMComponent::NoTrackFound(AliHLTMUONMansoTrackerFSM* tracker) | |
476 | { | |
477 | DebugTrace("No track found."); | |
478 | } |