1 /**************************************************************************
2 * This file is property of and copyright by the ALICE HLT Project *
3 * All rights reserved. *
6 * Artur Szostak <artursz@iafrica.com> *
7 * Indranil Das <indra.das@saha.ac.in> *
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 **************************************************************************/
21 /// @file AliHLTMUONMansoTrackerFSMComponent.cxx
22 /// @author Artur Szostak <artursz@iafrica.com>,
23 /// Indranil Das <indra.das@saha.ac.in>
25 /// @brief Implementation of AliHLTMUONMansoTrackerFSMComponent class.
28 #include "AliHLTMUONMansoTrackerFSMComponent.h"
29 #include "AliHLTMUONConstants.h"
30 #include "AliHLTMUONUtils.h"
31 #include "AliHLTMUONMansoTrackerFSM.h"
32 #include "AliHLTMUONDataBlockReader.h"
33 #include "AliHLTMUONDataBlockWriter.h"
39 ClassImp(AliHLTMUONMansoTrackerFSMComponent);
42 AliHLTMUONMansoTrackerFSMComponent::AliHLTMUONMansoTrackerFSMComponent() :
44 AliHLTMUONMansoTrackerFSMCallback(),
48 fRecHitBlockArraySize(0),
49 fWarnForUnexpecedBlock(false)
52 /// Default constructor.
55 for (Int_t i = 0; i < 4; i++)
57 fRecHitBlockCount[i] = 0;
58 fRecHitBlock[i] = NULL;
63 AliHLTMUONMansoTrackerFSMComponent::~AliHLTMUONMansoTrackerFSMComponent()
66 /// Default destructor.
69 assert( fTracker == NULL );
70 assert( fRecHitBlock[0] == NULL );
74 const char* AliHLTMUONMansoTrackerFSMComponent::GetComponentID()
77 /// Inherited from AliHLTComponent. Returns the component ID.
80 return AliHLTMUONConstants::MansoTrackerFSMId();
84 void AliHLTMUONMansoTrackerFSMComponent::GetInputDataTypes(
85 vector<AliHLTComponentDataType>& list
89 /// Inherited from AliHLTProcessor. Returns the list of expected input data types.
92 assert( list.empty() );
93 list.push_back( AliHLTMUONConstants::TriggerRecordsBlockDataType() );
94 list.push_back( AliHLTMUONConstants::RecHitsBlockDataType() );
98 AliHLTComponentDataType AliHLTMUONMansoTrackerFSMComponent::GetOutputDataType()
101 /// Inherited from AliHLTComponent. Returns the output data type.
104 return AliHLTMUONConstants::MansoTracksBlockDataType();
108 void AliHLTMUONMansoTrackerFSMComponent::GetOutputDataSize(
109 unsigned long& constBase, double& inputMultiplier
113 /// Inherited from AliHLTComponent. Returns an estimate of the expected output data size.
116 constBase = sizeof(AliHLTMUONMansoTracksBlockStruct);
121 AliHLTComponent* AliHLTMUONMansoTrackerFSMComponent::Spawn()
124 /// Inherited from AliHLTComponent. Creates a new object instance.
127 return new AliHLTMUONMansoTrackerFSMComponent;
131 int AliHLTMUONMansoTrackerFSMComponent::DoInit(int argc, const char** argv)
134 /// Inherited from AliHLTComponent.
135 /// Parses the command line parameters and initialises the component.
138 HLTInfo("Initialising dHLT manso tracker FSM component.");
142 fTracker = new AliHLTMUONMansoTrackerFSM();
144 catch (const std::bad_alloc&)
146 HLTError("Could not allocate more memory for the tracker component.");
149 fTracker->SetCallback(this);
151 fWarnForUnexpecedBlock = false;
153 for (int i = 0; i < argc; i++)
155 if (strcmp(argv[i], "-warn_on_unexpected_block") == 0)
157 fWarnForUnexpecedBlock = true;
161 HLTError("Unknown option '%s'.", argv[i]);
165 const int initArraySize = 10;
166 // allocate some initial memory for the reconstructed hit arrays.
169 fRecHitBlock[0] = new AliRecHitBlockInfo[initArraySize*4];
171 catch (const std::bad_alloc&)
173 HLTError("Could not allocate more memory for the reconstructed hit arrays.");
176 // Only set the arrays' size once we have successfully allocated the memory for the arrays.
177 fRecHitBlockArraySize = initArraySize;
178 // Now we need to set the pointers fRecHitBlock[i] {i>0} relative to fRecHitBlock[0].
179 for (Int_t i = 1; i < 4; i++)
181 fRecHitBlock[i] = fRecHitBlock[i-1] + fRecHitBlockArraySize;
183 // And reset the number of records actually stored in the arrays.
184 for (Int_t i = 0; i < 4; i++)
186 fRecHitBlockCount[i] = 0;
193 int AliHLTMUONMansoTrackerFSMComponent::DoDeinit()
196 /// Inherited from AliHLTComponent. Performs a cleanup of the component.
199 HLTInfo("Deinitialising dHLT manso tracker FSM component.");
201 if (fTracker != NULL)
207 // Remember that only fRecHitBlock[0] stores the pointer to the allocated memory.
208 // The other pointers are just reletive to this.
209 if (fRecHitBlock[0] != NULL)
210 delete [] fRecHitBlock[0];
212 fRecHitBlockArraySize = 0;
213 for (Int_t i = 0; i < 4; i++)
215 fRecHitBlockCount[i] = 0;
216 fRecHitBlock[i] = NULL;
223 int AliHLTMUONMansoTrackerFSMComponent::DoEvent(
224 const AliHLTComponentEventData& evtData,
225 const AliHLTComponentBlockData* blocks,
226 AliHLTComponentTriggerData& /*trigData*/,
227 AliHLTUInt8_t* outputPtr,
228 AliHLTUInt32_t& size,
229 std::vector<AliHLTComponentBlockData>& outputBlocks
233 /// Inherited from AliHLTProcessor. Processes the new event data.
237 AliHLTUInt32_t specification = 0; // Contains the output data block spec bits.
239 // Resize the rec hit arrays if we need to. To guarantee that they will not overflow
240 // we need to make sure each array is at least as big as the number of input data block.
241 if (fRecHitBlockArraySize < evtData.fBlockCnt)
243 // Release the old memory block and allocate more memory.
244 delete [] fRecHitBlock[0];
245 // Reset the number of records actually stored in the arrays.
246 for (Int_t i = 0; i < 4; i++)
248 fRecHitBlockCount[i] = 0;
253 fRecHitBlock[0] = new AliRecHitBlockInfo[evtData.fBlockCnt*4];
255 catch (const std::bad_alloc&)
257 HLTError("Could not allocate more memory for the reconstructed hit arrays.");
258 // Ok so now we need to clear all the pointers because we actually
259 // deleted the memory.
260 fRecHitBlockArraySize = 0;
261 for (Int_t i = 0; i < 4; i++)
263 fRecHitBlock[i] = NULL;
267 // Only set the arrays' size once we have successfully allocated the memory for the arrays.
268 fRecHitBlockArraySize = evtData.fBlockCnt;
269 // Now we need to set the pointers fRecHitBlock[i] {i>0} relative to fRecHitBlock[0].
270 for (Int_t i = 1; i < 4; i++)
272 fRecHitBlock[i] = fRecHitBlock[i-1] + fRecHitBlockArraySize;
276 AliHLTMUONMansoTracksBlockWriter block(outputPtr, size);
279 if (not block.InitCommonHeader())
281 Logging(kHLTLogError,
282 "AliHLTMUONMansoTrackerFSMComponent::DoEvent",
284 "The buffer is only %d bytes in size. We need a minimum of %d bytes.",
285 size, sizeof(AliHLTMUONMansoTracksBlockWriter::HeaderType)
287 size = 0; // Important to tell framework that nothing was generated.
291 // Loop over all input blocks in the event and add the ones that contain
292 // reconstructed hits into the hit buffers. The blocks containing trigger
293 // records are ignored for now and will be processed later.
294 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
296 if (blocks[n].fDataType == AliHLTMUONConstants::RecHitsBlockDataType())
298 specification |= blocks[n].fSpecification;
300 AliHLTMUONRecHitsBlockReader inblock(blocks[n].fPtr, blocks[n].fSize);
301 if (not inblock.BufferSizeOk())
303 size_t headerSize = sizeof(AliHLTMUONRecHitsBlockReader::HeaderType);
304 if (blocks[n].fSize < headerSize)
306 HLTError("Received a reconstructed hits data block with a size of %d bytes,"
307 " which is smaller than the minimum valid header size of %d bytes."
308 " The block must be corrupt.",
309 blocks[n].fSize, headerSize
314 size_t expectedWidth = sizeof(AliHLTMUONRecHitsBlockReader::ElementType);
315 if (inblock.CommonBlockHeader().fRecordWidth != expectedWidth)
317 HLTError("Received a reconstructed hits data block with a record"
318 " width of %d bytes, but the expected value is %d bytes."
319 " The block might be corrupt.",
320 inblock.CommonBlockHeader().fRecordWidth, expectedWidth
325 HLTError("Received a reconstructed hits data block with a size of %d bytes,"
326 " but the block header claims the block should be %d bytes."
327 " The block might be corrupt.",
328 blocks[n].fSize, inblock.BytesUsed()
333 if (inblock.Nentries() != 0)
334 AddRecHits(blocks[n].fSpecification, inblock.GetArray(), inblock.Nentries());
337 Logging(kHLTLogDebug,
338 "AliHLTMUONMansoTrackerFSMComponent::DoEvent",
340 "Received a reconstructed hits data block which contains no entries."
344 else if (blocks[n].fDataType != AliHLTMUONConstants::TriggerRecordsBlockDataType())
346 // Log a message indicating that we got a data block that we
347 // do not know how to handle.
348 char id[kAliHLTComponentDataTypefIDsize+1];
349 for (int i = 0; i < kAliHLTComponentDataTypefIDsize; i++)
350 id[i] = blocks[n].fDataType.fID[i];
351 id[kAliHLTComponentDataTypefIDsize] = '\0';
352 char origin[kAliHLTComponentDataTypefOriginSize+1];
353 for (int i = 0; i < kAliHLTComponentDataTypefOriginSize; i++)
354 origin[i] = blocks[n].fDataType.fOrigin[i];
355 origin[kAliHLTComponentDataTypefOriginSize] = '\0';
357 if (fWarnForUnexpecedBlock)
358 HLTWarning("Received a data block of a type we cannot handle: %s origin: %s",
359 static_cast<char*>(id), static_cast<char*>(origin)
362 HLTDebug("Received a data block of a type we cannot handle: %s origin: %s",
363 static_cast<char*>(id), static_cast<char*>(origin)
368 // Again loop over all input blocks in the event, but this time look for
369 // the trigger record blocks and process these.
370 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
372 if (blocks[n].fDataType != AliHLTMUONConstants::TriggerRecordsBlockDataType())
375 AliHLTMUONTriggerRecordsBlockReader inblock(blocks[n].fPtr, blocks[n].fSize);
376 if (not inblock.BufferSizeOk())
378 size_t headerSize = sizeof(AliHLTMUONTriggerRecordsBlockReader::HeaderType);
379 if (blocks[n].fSize < headerSize)
381 HLTError("Received a trigger records data block with a size of %d bytes,"
382 " which is smaller than the minimum valid header size of %d bytes."
383 " The block must be corrupt.",
384 blocks[n].fSize, headerSize
389 size_t expectedWidth = sizeof(AliHLTMUONTriggerRecordsBlockReader::ElementType);
390 if (inblock.CommonBlockHeader().fRecordWidth != expectedWidth)
392 HLTError("Received a trigger records data block with a record"
393 " width of %d bytes, but the expected value is %d bytes."
394 " The block might be corrupt.",
395 inblock.CommonBlockHeader().fRecordWidth, expectedWidth
400 HLTError("Received a trigger records data block with a size of %d bytes,"
401 " but the block header claims the block should be %d bytes."
402 " The block might be corrupt.",
403 blocks[n].fSize, inblock.BytesUsed()
407 DebugTrace("Processing a trigger block with "
408 << inblock.Nentries() << " entries."
411 specification |= blocks[n].fSpecification;
413 for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
415 fTracker->FindTrack(inblock[i]);
417 // Reset the tracker so that we do not double count tracks.
422 AliHLTComponentBlockData bd;
426 bd.fSize = block.BytesUsed();
427 bd.fDataType = AliHLTMUONConstants::MansoTracksBlockDataType();
428 bd.fSpecification = specification;
429 outputBlocks.push_back(bd);
430 size = block.BytesUsed();
436 void AliHLTMUONMansoTrackerFSMComponent::Reset()
439 /// Reset the track count and reconstructed hit data block arrays.
442 DebugTrace("Resetting AliHLTMUONMansoTrackerFSMComponent.");
444 //fTracker->Reset(); // Not necessary here because it is done after every FindTrack call.
446 fBlock = NULL; // Do not delete. Already done implicitly at the end of DoEvent.
447 for (int i = 0; i < 4; i++)
449 fRecHitBlockCount[i] = 0;
454 void AliHLTMUONMansoTrackerFSMComponent::AddRecHits(
455 AliHLTUInt32_t specification,
456 const AliHLTMUONRecHitStruct* recHits,
461 /// Adds a new reconstructed hit data block to the internal list of blocks
462 /// for the tracker to process.
463 /// These lists will later be used when the tracker requests them through
464 /// the callback method 'RequestClusters'.
467 DebugTrace("AliHLTMUONMansoTrackerFSMComponent::AddRecHits called with specification = 0x"
468 << std::hex << specification << std::dec << " and count = "
469 << count << " rec hits."
472 AliHLTUInt8_t chamberMap[20] = {
473 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10
476 // Identify the chamber the rec hits came from using the specifications field.
477 bool gotDataFromDDL[22];
478 AliHLTMUONUtils::UnpackSpecBits(specification, gotDataFromDDL);
480 AliHLTInt8_t chamber = -1;
481 for (int i = 0; i < 20; i++)
483 if (not gotDataFromDDL[i]) continue;
484 if (7 <= chamberMap[i] and chamberMap[i] <= 10)
486 if (chamber != -1 and chamber != chamberMap[i])
488 Logging(kHLTLogError,
489 "AliHLTMUONMansoTrackerFSMComponent::AddRecHits",
491 "Received a data block with data from multiple chambers."
492 " This component cannot handle such a case."
497 chamber = chamberMap[i];
501 Logging(kHLTLogError,
502 "AliHLTMUONMansoTrackerFSMComponent::AddRecHits",
504 "Received a data block with data from chamber %d"
505 " which is outside the expected range: [7..10].",
512 // Make sure we got one chamber number.
513 if (chamber < 7 or 10 < chamber)
515 Logging(kHLTLogError,
516 "AliHLTMUONMansoTrackerFSMComponent::AddRecHits",
518 "Received a reconstructed hit data block with a null specification."
519 " Cannot know which chamber the data comes from."
524 DebugTrace("Added " << count << " reconstructed hits from chamber "
525 << (int)chamber << " to the internal arrays."
528 assert( fRecHitBlockCount[chamber-7] < fRecHitBlockArraySize );
529 AliRecHitBlockInfo info(count, recHits);
530 fRecHitBlock[chamber-7][fRecHitBlockCount[chamber-7]] = info;
531 fRecHitBlockCount[chamber-7]++;
535 void AliHLTMUONMansoTrackerFSMComponent::RequestClusters(
536 AliHLTMUONMansoTrackerFSM* tracker,
537 AliHLTFloat32_t left, AliHLTFloat32_t right,
538 AliHLTFloat32_t bottom, AliHLTFloat32_t top,
539 AliHLTMUONChamberName chamber, const void* tag
543 /// Inherited from AliHLTMUONMansoTrackerFSMCallback.
544 /// This is the call back method used by the tracker algorithm to request
545 /// clusters on a certain chamber.
548 DebugTrace("AliHLTMUONMansoTracker::RequestClusters(chamber = " << chamber << ")");
549 void* ctag = const_cast<void*>(tag);
551 AliHLTUInt32_t recHitsCount = 0;
552 AliRecHitBlockInfo* recHitsBlock = NULL;
556 recHitsCount = fRecHitBlockCount[0];
557 recHitsBlock = fRecHitBlock[0];
562 recHitsCount = fRecHitBlockCount[1];
563 recHitsBlock = fRecHitBlock[1];
568 recHitsCount = fRecHitBlockCount[2];
569 recHitsBlock = fRecHitBlock[2];
574 recHitsCount = fRecHitBlockCount[3];
575 recHitsBlock = fRecHitBlock[3];
582 DebugTrace("Returning requested hits for chamber " << chNo << ":");
583 for (AliHLTUInt32_t i = 0; i < recHitsCount; i++)
584 for (AliHLTUInt32_t j = 0; j < recHitsBlock[i].Count(); j++)
586 const AliHLTMUONRecHitStruct* hit = &(recHitsBlock[i].Data()[j]);
587 if (left < hit->fX and hit->fX < right and bottom < hit->fY and hit->fY < top)
588 tracker->ReturnClusters(ctag, hit, 1);
590 DebugTrace("Done returning hits from chamber " << chNo << ".");
591 tracker->EndOfClusters(ctag);
595 void AliHLTMUONMansoTrackerFSMComponent::EndOfClusterRequests(
596 AliHLTMUONMansoTrackerFSM* /*tracker*/
600 /// Inherited from AliHLTMUONMansoTrackerFSMCallback.
601 /// Nothing special to do here.
604 DebugTrace("End of cluster requests.");
608 void AliHLTMUONMansoTrackerFSMComponent::FoundTrack(AliHLTMUONMansoTrackerFSM* tracker)
611 /// Inherited from AliHLTMUONMansoTrackerFSMCallback.
612 /// This is the call back method used by the tracker algorithm to declare
613 /// that a new track has been found.
616 DebugTrace("AliHLTMUONMansoTrackerFSMComponent::FoundTrack()");
618 AliHLTMUONMansoTracksBlockWriter* block =
619 reinterpret_cast<AliHLTMUONMansoTracksBlockWriter*>(fBlock);
621 AliHLTMUONMansoTrackStruct* track = block->AddEntry();
624 Logging(kHLTLogError,
625 "AliHLTMUONMansoTrackerFSMComponent::FoundTrack",
627 "We have overflowed the output buffer for Manso track data."
628 " The output buffer size is only %d bytes.",
635 tracker->FillTrackData(*track);
636 DebugTrace("\tTrack data = " << *track);
640 void AliHLTMUONMansoTrackerFSMComponent::NoTrackFound(AliHLTMUONMansoTrackerFSM* /*tracker*/)
643 /// Inherited from AliHLTMUONMansoTrackerFSMCallback.
644 /// Nothing special to do here.
647 DebugTrace("No track found.");