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 // Should never have the following 2 pointers non-NULL since DoDeinit
70 // should have been called before, but handle this case anyway.
71 if (fTracker != NULL) delete fTracker;
73 // Remember that only fRecHitBlock[0] stores the pointer to the allocated
74 // memory. The other pointers are just reletive to this.
75 if (fRecHitBlock[0] != NULL) delete [] fRecHitBlock[0];
79 const char* AliHLTMUONMansoTrackerFSMComponent::GetComponentID()
82 /// Inherited from AliHLTComponent. Returns the component ID.
85 return AliHLTMUONConstants::MansoTrackerFSMId();
89 void AliHLTMUONMansoTrackerFSMComponent::GetInputDataTypes(
90 vector<AliHLTComponentDataType>& list
94 /// Inherited from AliHLTProcessor. Returns the list of expected input data types.
97 assert( list.empty() );
98 list.push_back( AliHLTMUONConstants::TriggerRecordsBlockDataType() );
99 list.push_back( AliHLTMUONConstants::RecHitsBlockDataType() );
103 AliHLTComponentDataType AliHLTMUONMansoTrackerFSMComponent::GetOutputDataType()
106 /// Inherited from AliHLTComponent. Returns the output data type.
109 return AliHLTMUONConstants::MansoTracksBlockDataType();
113 void AliHLTMUONMansoTrackerFSMComponent::GetOutputDataSize(
114 unsigned long& constBase, double& inputMultiplier
118 /// Inherited from AliHLTComponent. Returns an estimate of the expected output data size.
121 constBase = sizeof(AliHLTMUONMansoTracksBlockStruct);
126 AliHLTComponent* AliHLTMUONMansoTrackerFSMComponent::Spawn()
129 /// Inherited from AliHLTComponent. Creates a new object instance.
132 return new AliHLTMUONMansoTrackerFSMComponent;
136 int AliHLTMUONMansoTrackerFSMComponent::DoInit(int argc, const char** argv)
139 /// Inherited from AliHLTComponent.
140 /// Parses the command line parameters and initialises the component.
143 HLTInfo("Initialising dHLT manso tracker FSM component.");
145 // Just in case for whatever reason we still have some of the internal
146 // object allocated previously still hanging around delete them now.
151 fTracker = new AliHLTMUONMansoTrackerFSM();
153 catch (const std::bad_alloc&)
155 HLTError("Could not allocate more memory for the tracker component.");
158 fTracker->SetCallback(this);
160 fWarnForUnexpecedBlock = false;
162 for (int i = 0; i < argc; i++)
164 if (strcmp(argv[i], "-warn_on_unexpected_block") == 0)
166 fWarnForUnexpecedBlock = true;
170 HLTError("Unknown option '%s'.", argv[i]);
171 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
175 const int initArraySize = 10;
176 // Allocate some initial memory for the reconstructed hit arrays.
179 fRecHitBlock[0] = new AliRecHitBlockInfo[initArraySize*4];
181 catch (const std::bad_alloc&)
183 HLTError("Could not allocate more memory for the reconstructed hit arrays.");
184 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
187 // Only set the arrays' size once we have successfully allocated the memory for the arrays.
188 fRecHitBlockArraySize = initArraySize;
189 // Now we need to set the pointers fRecHitBlock[i] {i>0} relative to fRecHitBlock[0].
190 for (Int_t i = 1; i < 4; i++)
192 fRecHitBlock[i] = fRecHitBlock[i-1] + fRecHitBlockArraySize;
194 // And reset the number of records actually stored in the arrays.
195 for (Int_t i = 0; i < 4; i++)
197 fRecHitBlockCount[i] = 0;
204 int AliHLTMUONMansoTrackerFSMComponent::DoDeinit()
207 /// Inherited from AliHLTComponent. Performs a cleanup of the component.
210 HLTInfo("Deinitialising dHLT manso tracker FSM component.");
216 int AliHLTMUONMansoTrackerFSMComponent::DoEvent(
217 const AliHLTComponentEventData& evtData,
218 const AliHLTComponentBlockData* blocks,
219 AliHLTComponentTriggerData& /*trigData*/,
220 AliHLTUInt8_t* outputPtr,
221 AliHLTUInt32_t& size,
222 std::vector<AliHLTComponentBlockData>& outputBlocks
226 /// Inherited from AliHLTProcessor. Processes the new event data.
230 AliHLTUInt32_t specification = 0; // Contains the output data block spec bits.
232 // Resize the rec hit arrays if we possibly will need more space.
233 // To guarantee that they will not overflow we need to make sure each
234 // array is at least as big as the number of input data blocks.
235 if (fRecHitBlockArraySize < evtData.fBlockCnt)
237 // Release the old memory block and allocate more memory.
238 if (fRecHitBlock[0] != NULL)
240 delete [] fRecHitBlock[0];
243 // Reset the number of records actually stored in the arrays.
244 for (Int_t i = 0; i < 4; i++)
246 fRecHitBlockCount[i] = 0;
251 fRecHitBlock[0] = new AliRecHitBlockInfo[evtData.fBlockCnt*4];
253 catch (const std::bad_alloc&)
255 HLTError("Could not allocate more memory for the reconstructed hit arrays.");
256 // Ok so now we need to clear all the pointers because we actually
257 // deleted the memory.
258 fRecHitBlockArraySize = 0;
259 for (Int_t i = 0; i < 4; i++)
261 fRecHitBlock[i] = NULL;
265 // Only set the arrays' size once we have successfully allocated the memory for the arrays.
266 fRecHitBlockArraySize = evtData.fBlockCnt;
267 // Now we need to set the pointers fRecHitBlock[i] {i>0} relative to fRecHitBlock[0].
268 for (Int_t i = 1; i < 4; i++)
270 fRecHitBlock[i] = fRecHitBlock[i-1] + fRecHitBlockArraySize;
274 AliHLTMUONMansoTracksBlockWriter block(outputPtr, size);
277 if (not block.InitCommonHeader())
279 Logging(kHLTLogError,
280 "AliHLTMUONMansoTrackerFSMComponent::DoEvent",
282 "The buffer is only %d bytes in size. We need a minimum of %d bytes.",
283 size, sizeof(AliHLTMUONMansoTracksBlockWriter::HeaderType)
285 size = 0; // Important to tell framework that nothing was generated.
289 // Loop over all input blocks in the event and add the ones that contain
290 // reconstructed hits into the hit buffers. The blocks containing trigger
291 // records are ignored for now and will be processed later.
292 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
294 HLTDebug("Handling block: %u, with fDataType = '%s', fPtr = %p and fSize = %u bytes.",
295 n, DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fPtr, blocks[n].fSize
298 if (blocks[n].fDataType == AliHLTMUONConstants::RecHitsBlockDataType())
300 specification |= blocks[n].fSpecification;
302 AliHLTMUONRecHitsBlockReader inblock(blocks[n].fPtr, blocks[n].fSize);
303 if (not inblock.BufferSizeOk())
305 size_t headerSize = sizeof(AliHLTMUONRecHitsBlockReader::HeaderType);
306 if (blocks[n].fSize < headerSize)
308 HLTError("Received a reconstructed hits data block with a size of %d bytes,"
309 " which is smaller than the minimum valid header size of %d bytes."
310 " The block must be corrupt.",
311 blocks[n].fSize, headerSize
316 size_t expectedWidth = sizeof(AliHLTMUONRecHitsBlockReader::ElementType);
317 if (inblock.CommonBlockHeader().fRecordWidth != expectedWidth)
319 HLTError("Received a reconstructed hits data block with a record"
320 " width of %d bytes, but the expected value is %d bytes."
321 " The block might be corrupt.",
322 inblock.CommonBlockHeader().fRecordWidth, expectedWidth
327 HLTError("Received a reconstructed hits data block with a size of %d bytes,"
328 " but the block header claims the block should be %d bytes."
329 " The block might be corrupt.",
330 blocks[n].fSize, inblock.BytesUsed()
335 if (inblock.Nentries() != 0)
336 AddRecHits(blocks[n].fSpecification, inblock.GetArray(), inblock.Nentries());
339 Logging(kHLTLogDebug,
340 "AliHLTMUONMansoTrackerFSMComponent::DoEvent",
342 "Received a reconstructed hits data block which contains no entries."
346 else if (blocks[n].fDataType != AliHLTMUONConstants::TriggerRecordsBlockDataType())
348 // Log a message indicating that we got a data block that we
349 // do not know how to handle.
350 if (fWarnForUnexpecedBlock)
351 HLTWarning("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
352 DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification
355 HLTDebug("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
356 DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification
361 // Again loop over all input blocks in the event, but this time look for
362 // the trigger record blocks and process these.
363 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
365 if (blocks[n].fDataType != AliHLTMUONConstants::TriggerRecordsBlockDataType())
368 AliHLTMUONTriggerRecordsBlockReader inblock(blocks[n].fPtr, blocks[n].fSize);
369 if (not inblock.BufferSizeOk())
371 size_t headerSize = sizeof(AliHLTMUONTriggerRecordsBlockReader::HeaderType);
372 if (blocks[n].fSize < headerSize)
374 HLTError("Received a trigger records data block with a size of %d bytes,"
375 " which is smaller than the minimum valid header size of %d bytes."
376 " The block must be corrupt.",
377 blocks[n].fSize, headerSize
382 size_t expectedWidth = sizeof(AliHLTMUONTriggerRecordsBlockReader::ElementType);
383 if (inblock.CommonBlockHeader().fRecordWidth != expectedWidth)
385 HLTError("Received a trigger records data block with a record"
386 " width of %d bytes, but the expected value is %d bytes."
387 " The block might be corrupt.",
388 inblock.CommonBlockHeader().fRecordWidth, expectedWidth
393 HLTError("Received a trigger records data block with a size of %d bytes,"
394 " but the block header claims the block should be %d bytes."
395 " The block might be corrupt.",
396 blocks[n].fSize, inblock.BytesUsed()
400 DebugTrace("Processing a trigger block with "
401 << inblock.Nentries() << " entries."
404 specification |= blocks[n].fSpecification;
406 for (AliHLTUInt32_t i = 0; i < inblock.Nentries(); i++)
408 fTracker->FindTrack(inblock[i]);
410 // Reset the tracker so that we do not double count tracks.
415 AliHLTComponentBlockData bd;
419 bd.fSize = block.BytesUsed();
420 bd.fDataType = AliHLTMUONConstants::MansoTracksBlockDataType();
421 bd.fSpecification = specification;
422 outputBlocks.push_back(bd);
423 size = block.BytesUsed();
429 void AliHLTMUONMansoTrackerFSMComponent::Reset()
432 /// Reset the track count and reconstructed hit data block arrays.
435 DebugTrace("Resetting AliHLTMUONMansoTrackerFSMComponent.");
437 //fTracker->Reset(); // Not necessary here because it is done after every FindTrack call.
439 fBlock = NULL; // Do not delete. Already done implicitly at the end of DoEvent.
440 for (int i = 0; i < 4; i++)
442 fRecHitBlockCount[i] = 0;
447 void AliHLTMUONMansoTrackerFSMComponent::FreeMemory()
449 /// Deletes any objects and arrays allocated by this component and releases
450 /// the memory used. This is called as a helper routine by the init and deinit
451 /// methods. If some or all of the object pointers are already NULL then
452 /// nothing is done for those. This method guarantees that all the relevant
453 /// pointers will be NULL after returning from this method.
455 if (fTracker != NULL)
461 // Remember that only fRecHitBlock[0] stores the pointer to the allocated memory.
462 // The other pointers are just reletive to this.
463 if (fRecHitBlock[0] != NULL)
464 delete [] fRecHitBlock[0];
466 fRecHitBlockArraySize = 0;
467 for (Int_t i = 0; i < 4; i++)
469 fRecHitBlockCount[i] = 0;
470 fRecHitBlock[i] = NULL;
475 void AliHLTMUONMansoTrackerFSMComponent::AddRecHits(
476 AliHLTUInt32_t specification,
477 const AliHLTMUONRecHitStruct* recHits,
482 /// Adds a new reconstructed hit data block to the internal list of blocks
483 /// for the tracker to process.
484 /// These lists will later be used when the tracker requests them through
485 /// the callback method 'RequestClusters'.
488 DebugTrace("AliHLTMUONMansoTrackerFSMComponent::AddRecHits called with specification = 0x"
489 << std::hex << specification << std::dec << " and count = "
490 << count << " rec hits."
493 AliHLTUInt8_t chamberMap[20] = {
494 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10
497 // Identify the chamber the rec hits came from using the specifications field.
498 bool gotDataFromDDL[22];
499 AliHLTMUONUtils::UnpackSpecBits(specification, gotDataFromDDL);
501 AliHLTInt8_t chamber = -1;
502 for (int i = 0; i < 20; i++)
504 if (not gotDataFromDDL[i]) continue;
505 if (7 <= chamberMap[i] and chamberMap[i] <= 10)
507 if (chamber != -1 and chamber != chamberMap[i])
509 Logging(kHLTLogError,
510 "AliHLTMUONMansoTrackerFSMComponent::AddRecHits",
512 "Received a data block with data from multiple chambers."
513 " This component cannot handle such a case."
518 chamber = chamberMap[i];
522 Logging(kHLTLogError,
523 "AliHLTMUONMansoTrackerFSMComponent::AddRecHits",
525 "Received a data block with data from chamber %d"
526 " which is outside the expected range: [7..10].",
533 // Make sure we got one chamber number.
534 if (chamber < 7 or 10 < chamber)
536 Logging(kHLTLogError,
537 "AliHLTMUONMansoTrackerFSMComponent::AddRecHits",
539 "Received a reconstructed hit data block with a null specification."
540 " Cannot know which chamber the data comes from."
545 DebugTrace("Added " << count << " reconstructed hits from chamber "
546 << (int)chamber << " to the internal arrays."
549 assert( fRecHitBlockCount[chamber-7] < fRecHitBlockArraySize );
550 AliRecHitBlockInfo info(count, recHits);
551 fRecHitBlock[chamber-7][fRecHitBlockCount[chamber-7]] = info;
552 fRecHitBlockCount[chamber-7]++;
556 void AliHLTMUONMansoTrackerFSMComponent::RequestClusters(
557 AliHLTMUONMansoTrackerFSM* tracker,
558 AliHLTFloat32_t left, AliHLTFloat32_t right,
559 AliHLTFloat32_t bottom, AliHLTFloat32_t top,
560 AliHLTMUONChamberName chamber, const void* tag
564 /// Inherited from AliHLTMUONMansoTrackerFSMCallback.
565 /// This is the call back method used by the tracker algorithm to request
566 /// clusters on a certain chamber.
569 DebugTrace("AliHLTMUONMansoTracker::RequestClusters(chamber = " << chamber << ")");
570 void* ctag = const_cast<void*>(tag);
572 AliHLTUInt32_t recHitsCount = 0;
573 AliRecHitBlockInfo* recHitsBlock = NULL;
577 recHitsCount = fRecHitBlockCount[0];
578 recHitsBlock = fRecHitBlock[0];
583 recHitsCount = fRecHitBlockCount[1];
584 recHitsBlock = fRecHitBlock[1];
589 recHitsCount = fRecHitBlockCount[2];
590 recHitsBlock = fRecHitBlock[2];
595 recHitsCount = fRecHitBlockCount[3];
596 recHitsBlock = fRecHitBlock[3];
603 DebugTrace("Returning requested hits for chamber " << chNo << ":");
604 for (AliHLTUInt32_t i = 0; i < recHitsCount; i++)
605 for (AliHLTUInt32_t j = 0; j < recHitsBlock[i].Count(); j++)
607 const AliHLTMUONRecHitStruct* hit = &(recHitsBlock[i].Data()[j]);
608 if (left < hit->fX and hit->fX < right and bottom < hit->fY and hit->fY < top)
609 tracker->ReturnClusters(ctag, hit, 1);
611 DebugTrace("Done returning hits from chamber " << chNo << ".");
612 tracker->EndOfClusters(ctag);
616 void AliHLTMUONMansoTrackerFSMComponent::EndOfClusterRequests(
617 AliHLTMUONMansoTrackerFSM* /*tracker*/
621 /// Inherited from AliHLTMUONMansoTrackerFSMCallback.
622 /// Nothing special to do here.
625 DebugTrace("End of cluster requests.");
629 void AliHLTMUONMansoTrackerFSMComponent::FoundTrack(AliHLTMUONMansoTrackerFSM* tracker)
632 /// Inherited from AliHLTMUONMansoTrackerFSMCallback.
633 /// This is the call back method used by the tracker algorithm to declare
634 /// that a new track has been found.
637 DebugTrace("AliHLTMUONMansoTrackerFSMComponent::FoundTrack()");
639 AliHLTMUONMansoTracksBlockWriter* block =
640 reinterpret_cast<AliHLTMUONMansoTracksBlockWriter*>(fBlock);
642 AliHLTMUONMansoTrackStruct* track = block->AddEntry();
645 Logging(kHLTLogError,
646 "AliHLTMUONMansoTrackerFSMComponent::FoundTrack",
648 "We have overflowed the output buffer for Manso track data."
649 " The output buffer size is only %d bytes.",
656 tracker->FillTrackData(*track);
657 DebugTrace("\tTrack data = " << *track);
661 void AliHLTMUONMansoTrackerFSMComponent::NoTrackFound(AliHLTMUONMansoTrackerFSM* /*tracker*/)
664 /// Inherited from AliHLTMUONMansoTrackerFSMCallback.
665 /// Nothing special to do here.
668 DebugTrace("No track found.");