The DumpEvent methods should be protected, not private, because classes need to inher...
[u/mrichter/AliRoot.git] / HLT / MUON / OnlineAnalysis / AliHLTMUONMansoTrackerFSMComponent.cxx
CommitLineData
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
38namespace
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
47ClassImp(AliHLTMUONMansoTrackerFSMComponent);
48
49
50AliHLTMUONMansoTrackerFSMComponent::AliHLTMUONMansoTrackerFSMComponent() :
51 AliHLTProcessor(),
52 AliHLTMUONMansoTrackerFSMCallback(),
53 fTracker(NULL),
54 fTrackCount(0),
d42549e3 55 fBlock(NULL),
56 fWarnForUnexpecedBlock(false)
b92524d0 57{
58}
59
60
61AliHLTMUONMansoTrackerFSMComponent::~AliHLTMUONMansoTrackerFSMComponent()
62{
63 assert( fTracker == NULL );
64}
65
66
67const char* AliHLTMUONMansoTrackerFSMComponent::GetComponentID()
68{
69 return AliHLTMUONConstants::MansoTrackerFSMId();
70}
71
72
73void 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
83AliHLTComponentDataType AliHLTMUONMansoTrackerFSMComponent::GetOutputDataType()
84{
85 return AliHLTMUONConstants::MansoTracksBlockDataType();
86}
87
88
89void AliHLTMUONMansoTrackerFSMComponent::GetOutputDataSize(
90 unsigned long& constBase, double& inputMultiplier
91 )
92{
93 constBase = sizeof(AliHLTMUONMansoTracksBlockStruct);
94 inputMultiplier = 1;
95}
96
97
98AliHLTComponent* AliHLTMUONMansoTrackerFSMComponent::Spawn()
99{
100 return new AliHLTMUONMansoTrackerFSMComponent;
101}
102
103
104int 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
121int AliHLTMUONMansoTrackerFSMComponent::DoDeinit()
122{
123 if (fTracker != NULL)
124 {
125 delete fTracker;
126 fTracker = NULL;
127 }
128 return 0;
129}
130
131
132int AliHLTMUONMansoTrackerFSMComponent::DoEvent(
133 const AliHLTComponentEventData& evtData,
5def1693 134 const AliHLTComponentBlockData* blocks,
135 AliHLTComponentTriggerData& /*trigData*/,
136 AliHLTUInt8_t* outputPtr,
b92524d0 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 = &block;
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
304void 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
318void 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
392void 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
441void AliHLTMUONMansoTrackerFSMComponent::EndOfClusterRequests(
5def1693 442 AliHLTMUONMansoTrackerFSM* /*tracker*/
b92524d0 443 )
444{
445 DebugTrace("End of cluster requests.");
446}
447
448
449void 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
5def1693 475void AliHLTMUONMansoTrackerFSMComponent::NoTrackFound(AliHLTMUONMansoTrackerFSM* /*tracker*/)
b92524d0 476{
477 DebugTrace("No track found.");
478}