/**************************************************************************
- * This file is property of and copyright by the ALICE HLT Project *
+ * This file is property of and copyright by the ALICE HLT Project *
* All rights reserved. *
* *
* Primary Authors: *
* without fee, provided that the above copyright notice appears in all *
* copies and that both the copyright notice and this permission notice *
* appear in the supporting documentation. The authors make no claims *
- * about the suitability of this software for any purpose. It is *
+ * about the suitability of this software for any purpose. It is *
* provided "as is" without express or implied warranty. *
**************************************************************************/
-/* $Id$ */
+// $Id$
///
/// @file AliHLTMUONMansoTrackerFSMComponent.cxx
/// @author Artur Szostak <artursz@iafrica.com>,
/// Indranil Das <indra.das@saha.ac.in>
-/// @date
+/// @date 18 Sep 2007
/// @brief Implementation of AliHLTMUONMansoTrackerFSMComponent class.
///
fBlock(NULL),
fRecHitBlockArraySize(0),
fWarnForUnexpecedBlock(false),
- fDelaySetup(false),
fCanLoadZmiddle(true),
fCanLoadBL(true)
{
void AliHLTMUONMansoTrackerFSMComponent::GetInputDataTypes(
- vector<AliHLTComponentDataType>& list
+ AliHLTComponentDataTypeList& list
)
{
///
/// Inherited from AliHLTComponent. Returns the output data type.
///
- return AliHLTMUONConstants::MansoTracksBlockDataType();
+ return kAliHLTMultipleDataType;
+}
+
+
+int AliHLTMUONMansoTrackerFSMComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& list)
+{
+ /// Inherited from AliHLTComponent. Returns the output data types.
+
+ assert( list.empty() );
+ list.push_back( AliHLTMUONConstants::MansoTracksBlockDataType() );
+ list.push_back( AliHLTMUONConstants::MansoCandidatesBlockDataType() );
+ return list.size();
}
/// Inherited from AliHLTComponent. Returns an estimate of the expected output data size.
///
- constBase = sizeof(AliHLTMUONMansoTracksBlockStruct);
+ constBase = sizeof(AliHLTMUONMansoTracksBlockStruct) + 1024*1024;
inputMultiplier = 1;
}
HLTInfo("Initialising dHLT manso tracker FSM component.");
+ // Inherit the parents functionality.
+ int result = AliHLTMUONProcessor::DoInit(argc, argv);
+ if (result != 0) return result;
+
// Just in case for whatever reason we still have some of the internal
// object allocated previously still hanging around delete them now.
FreeMemory();
- try
- {
- fTracker = new AliHLTMUONMansoTrackerFSM();
- }
- catch (const std::bad_alloc&)
- {
- HLTError("Could not allocate more memory for the tracker component.");
- return -ENOMEM;
- }
- fTracker->SetCallback(this);
-
fWarnForUnexpecedBlock = false;
- fDelaySetup = false;
+ bool makeCandidates = false;
ResetCanLoadFlags();
-
- const char* cdbPath = NULL;
- Int_t run = -1;
double zmiddle = 0;
double bfieldintegral = 0;
double roiA[4] = {0, 0, 0, 0};
for (int i = 0; i < argc; i++)
{
- if (strcmp( argv[i], "-cdbpath" ) == 0)
- {
- if (cdbPath != NULL)
- {
- HLTWarning("CDB path was already specified."
- " Will replace previous value given by -cdbpath."
- );
- }
-
- if ( argc <= i+1 )
- {
- HLTError("The CDB path was not specified." );
- FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
- return -EINVAL;
- }
- cdbPath = argv[i+1];
- i++;
- continue;
- }
-
- if (strcmp( argv[i], "-run" ) == 0)
- {
- if (run != -1)
- {
- HLTWarning("Run number was already specified."
- " Will replace previous value given by -run."
- );
- }
-
- if ( argc <= i+1 )
- {
- HLTError("The run number was not specified." );
- FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
- return -EINVAL;
- }
-
- char* cpErr = NULL;
- run = Int_t( strtoul(argv[i+1], &cpErr, 0) );
- if (cpErr == NULL or *cpErr != '\0')
- {
- HLTError("Cannot convert '%s' to a valid run number."
- " Expected a positive integer value.", argv[i+1]
- );
- FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
- return -EINVAL;
- }
-
- i++;
- continue;
- }
-
+ if (ArgumentAlreadyHandled(i, argv[i])) continue;
+
if (strcmp( argv[i], "-zmiddle" ) == 0)
{
if (not fCanLoadZmiddle)
if ( argc <= i+1 )
{
HLTError("The Z coordinate for the middle of the dipole was not specified." );
- FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
return -EINVAL;
}
HLTError("Cannot convert '%s' to a valid floating point number.",
argv[i+1]
);
- FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
return -EINVAL;
}
if ( argc <= i+1 )
{
HLTError("The magnetic field integral was not specified." );
- FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
return -EINVAL;
}
HLTError("Cannot convert '%s' to a valid floating point number.",
argv[i+1]
);
- FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
return -EINVAL;
}
if ( argc <= i+1 )
{
HLTError("The region of interest parameter was not specified." );
- FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
return -EINVAL;
}
HLTError("Cannot convert '%s' to a valid floating point number.",
argv[i+1]
);
- FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
return -EINVAL;
}
if ( argc <= i+1 )
{
HLTError("The region of interest parameter was not specified." );
- FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
return -EINVAL;
}
HLTError("Cannot convert '%s' to a valid floating point number.",
argv[i+1]
);
- FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
return -EINVAL;
}
if ( argc <= i+1 )
{
HLTError("The region of interest parameter was not specified." );
- FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
return -EINVAL;
}
HLTError("Cannot convert '%s' to a valid floating point number.",
argv[i+1]
);
- FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
return -EINVAL;
}
continue;
}
- if (strcmp( argv[i], "-delaysetup" ) == 0)
+ if (strcmp(argv[i], "-warn_on_unexpected_block") == 0)
{
- fDelaySetup = true;
+ fWarnForUnexpecedBlock = true;
continue;
}
- if (strcmp(argv[i], "-warn_on_unexpected_block") == 0)
+ if (strcmp(argv[i], "-makecandidates") == 0)
{
- fWarnForUnexpecedBlock = true;
+ makeCandidates = true;
continue;
}
-
+
HLTError("Unknown option '%s'.", argv[i]);
- FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
return -EINVAL;
}
- if (cdbPath != NULL or run != -1)
+ try
{
- int result = SetCDBPathAndRunNo(cdbPath, run);
- if (result != 0)
- {
- // Error messages already generated in SetCDBPathAndRunNo.
- FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
- return result;
- }
+ fTracker = new AliHLTMUONMansoTrackerFSM();
}
+ catch (const std::bad_alloc&)
+ {
+ HLTError("Could not allocate more memory for the tracker component.");
+ return -ENOMEM;
+ }
+ fTracker->SetCallback(this);
+ fTracker->MakeCandidates(makeCandidates);
// Set all the parameters that were found on the command line.
if (not fCanLoadZmiddle) AliHLTMUONCalculations::Zf(zmiddle);
if (not fCanLoadZ[4]) fTracker->SetZ11(chamberZ[4]);
if (not fCanLoadZ[5]) fTracker->SetZ13(chamberZ[5]);
- if (not fDelaySetup)
+ if (not DelaySetup())
{
if (AtLeastOneCanLoadFlagsIsSet())
{
HLTInfo("Loading configuration parameters from CDB.");
- int result = ReadConfigFromCDB();
+ result = ReadConfigFromCDB();
if (result != 0)
{
// Error messages already generated in ReadConfigFromCDB.
/// then new configuration parameters are loaded, otherwise nothing is done.
/// \param componentId The name of the component in the current chain.
- bool givenConfigPath = strcmp(cdbEntry, AliHLTMUONConstants::MansoTrackerFSMCDBPath()) == 0;
+ TString path = cdbEntry;
+ bool givenConfigPath = (path == AliHLTMUONConstants::MansoTrackerFSMCDBPath());
if (cdbEntry == NULL or givenConfigPath)
{
if (fCanLoadBL)
{
- result = GetFloatFromTMap(map, "bfieldintegral", value, pathToEntry, "integrated magnetic field");
- if (result != 0) return result;
- AliHLTMUONCalculations::QBL(value);
+ Double_t bfieldintegral;
+ result = FetchFieldIntegral(bfieldintegral);
+ if (result == 0)
+ {
+ AliHLTMUONCalculations::QBL(bfieldintegral);
+ }
+ else
+ {
+ HLTWarning("Failed to load the magnetic field integral from GRP information.");
+ result = GetFloatFromTMap(map, "bfieldintegral", value, pathToEntry, "integrated magnetic field");
+ if (result != 0) return result;
+ HLTWarning(Form("Using deprecated magnetic field integral value of %f T.m.", value));
+ AliHLTMUONCalculations::QBL(value);
+ }
}
if (fCanLoadA[0])
int AliHLTMUONMansoTrackerFSMComponent::DoEvent(
const AliHLTComponentEventData& evtData,
const AliHLTComponentBlockData* blocks,
- AliHLTComponentTriggerData& /*trigData*/,
+ AliHLTComponentTriggerData& trigData,
AliHLTUInt8_t* outputPtr,
AliHLTUInt32_t& size,
- std::vector<AliHLTComponentBlockData>& outputBlocks
+ AliHLTComponentBlockDataList& outputBlocks
)
{
///
// Initialise the configuration parameters from CDB if we were
// requested to initialise only when the first event was received.
- if (fDelaySetup)
+ if (DelaySetup())
{
// Load the configuration paramters from CDB if they have not
// been given on the command line.
if (result != 0) return result;
}
- fDelaySetup = false;
+ DoneDelayedSetup();
ResetCanLoadFlags(); // From this point read all parameters from CDB.
}
{
fRecHitBlock[i] = NULL;
}
+ if (DumpDataOnError()) DumpEvent(evtData, blocks, trigData, outputPtr, size, outputBlocks);
return -ENOMEM;
}
// Only set the arrays' size once we have successfully allocated the memory for the arrays.
"The buffer is only %d bytes in size. We need a minimum of %d bytes.",
size, sizeof(AliHLTMUONMansoTracksBlockWriter::HeaderType)
);
+ if (DumpDataOnError()) DumpEvent(evtData, blocks, trigData, outputPtr, size, outputBlocks);
size = 0; // Important to tell framework that nothing was generated.
return -ENOBUFS;
}
specification |= blocks[n].fSpecification;
AliHLTMUONRecHitsBlockReader inblock(blocks[n].fPtr, blocks[n].fSize);
- if (not BlockStructureOk(inblock)) continue;
+ if (not BlockStructureOk(inblock))
+ {
+ if (DumpDataOnError()) DumpEvent(evtData, blocks, trigData, outputPtr, size, outputBlocks);
+ continue;
+ }
if (inblock.Nentries() != 0)
AddRecHits(blocks[n].fSpecification, inblock.GetArray(), inblock.Nentries());
HLTWarning("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification
);
+#ifdef __DEBUG
else
HLTDebug("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification
);
+#endif
}
}
continue;
AliHLTMUONTriggerRecordsBlockReader inblock(blocks[n].fPtr, blocks[n].fSize);
- if (not BlockStructureOk(inblock)) continue;
+ if (not BlockStructureOk(inblock))
+ {
+ if (DumpDataOnError()) DumpEvent(evtData, blocks, trigData, outputPtr, size, outputBlocks);
+ continue;
+ }
DebugTrace("Processing a trigger block with "
<< inblock.Nentries() << " entries."
bd.fDataType = AliHLTMUONConstants::MansoTracksBlockDataType();
bd.fSpecification = specification;
outputBlocks.push_back(bd);
- size = block.BytesUsed();
-
+ AliHLTUInt32_t totalSize = block.BytesUsed();
+
+ if (fTracker->MakeCandidates())
+ {
+ AliHLTMUONMansoCandidatesBlockWriter candidatesBlock(outputPtr+totalSize, size-totalSize);
+ if (not candidatesBlock.InitCommonHeader())
+ {
+ HLTError("Buffer overflowed. There are only %d bytes left in the buffer,"
+ " but we need a minimum of %d bytes.",
+ size, sizeof(AliHLTMUONMansoCandidatesBlockWriter::HeaderType)
+ );
+ if (DumpDataOnError()) DumpEvent(evtData, blocks, trigData, outputPtr, size, outputBlocks);
+ size = 0; // Important to tell framework that nothing was generated.
+ return -ENOBUFS;
+ }
+
+ // Fill in the output block buffer.
+ candidatesBlock.SetNumberOfEntries(fTracker->TrackCandidatesCount());
+ for (AliHLTUInt32_t i = 0; i < fTracker->TrackCandidatesCount(); ++i)
+ {
+ candidatesBlock[i] = fTracker->TrackCandidates()[i];
+ }
+
+ fTracker->ZeroTrackCandidatesList();
+
+ AliHLTComponentBlockData bdc;
+ FillBlockData(bdc);
+ bdc.fPtr = outputPtr;
+ bdc.fOffset = totalSize;
+ bdc.fSize = candidatesBlock.BytesUsed();
+ bdc.fDataType = AliHLTMUONConstants::MansoCandidatesBlockDataType();
+ bdc.fSpecification = specification;
+ outputBlocks.push_back(bdc);
+ totalSize += candidatesBlock.BytesUsed();
+ }
+
+ size = totalSize;
return 0;
}
}
else
{
- Logging(kHLTLogError,
- "AliHLTMUONMansoTrackerFSMComponent::AddRecHits",
- "Invalid chamber",
- "Received a data block with data from chamber %d"
- " which is outside the expected range: [7..10].",
- chamberMap[i]
- );
+ if (fWarnForUnexpecedBlock)
+ {
+ Logging(kHLTLogWarning,
+ "AliHLTMUONMansoTrackerFSMComponent::AddRecHits",
+ "Invalid chamber",
+ "Received a data block with data from chamber %d"
+ " which is outside the expected range: [7..10].",
+ chamberMap[i]
+ );
+ }
return;
}
}
AliHLTMUONMansoTracksBlockWriter* block =
reinterpret_cast<AliHLTMUONMansoTracksBlockWriter*>(fBlock);
- AliHLTMUONMansoTrackStruct* track = block->AddEntry();
- if (track == NULL)
+ AliHLTMUONMansoTrackStruct newTrack;
+ tracker->FillTrackData(newTrack);
+
+ // The indicies of the duplicate tracks. If set to block->Nentries() then
+ // this indicates the index is not used.
+ AliHLTUInt32_t dup1 = block->Nentries();
+ AliHLTUInt32_t dup2 = block->Nentries();
+
+ // Check if there are any tracks that use the same hits as the one found.
+ // If there are, then use the one that has the highest pT.
+ // There will be at most 2 duplicate tracks.
+ for (AliHLTUInt32_t i = 0; i < block->Nentries(); i++)
{
- Logging(kHLTLogError,
- "AliHLTMUONMansoTrackerFSMComponent::FoundTrack",
- "Buffer overflow",
- "We have overflowed the output buffer for Manso track data."
- " The output buffer size is only %d bytes.",
- block->BufferSize()
- );
- return;
+ AliHLTMUONMansoTrackStruct& track = (*block)[i];
+ bool hasNoDuplicates = true;
+ for (AliHLTUInt32_t j = 0; j < 4; j++)
+ {
+ if (track.fHit[j] == AliHLTMUONConstants::NilRecHitStruct()) continue;
+ if (newTrack.fHit[j] == AliHLTMUONConstants::NilRecHitStruct()) continue;
+ if (track.fHit[j] == newTrack.fHit[j])
+ {
+ hasNoDuplicates = false;
+ break;
+ }
+ }
+ if (hasNoDuplicates) continue;
+
+ if (dup1 == block->Nentries())
+ {
+ dup1 = i;
+ }
+ else if (dup2 == block->Nentries())
+ {
+ dup2 = i;
+ }
+ else
+ {
+ HLTError("Found more than 2 tracks with duplicate hits. This is completely unexpected. Something is seriously wrong!");
+ }
+ }
+
+ if (dup1 != block->Nentries() and dup2 != block->Nentries())
+ {
+ // In this case we found 2 duplicate entries.
+ // Figure out which one has the highest pT and keep only that one.
+ AliHLTMUONMansoTrackStruct& track1 = (*block)[dup1];
+ AliHLTMUONMansoTrackStruct& track2 = (*block)[dup2];
+ double newPt = sqrt(newTrack.fPx * newTrack.fPx + newTrack.fPy * newTrack.fPy);
+ double dupPt1 = sqrt(track1.fPx * track1.fPx + track1.fPy * track1.fPy);
+ double dupPt2 = sqrt(track2.fPx * track2.fPx + track2.fPy * track2.fPy);
+
+ if (newPt >= dupPt1 and newPt >= dupPt2)
+ {
+ // The new track must replace both existing tracks.
+ track1 = newTrack;
+ track2 = (*block)[block->Nentries()-1];
+ }
+ else if (dupPt1 >= newPt and dupPt1 >= dupPt2)
+ {
+ // track1 has the highest pT so ignore the new track and delete track2.
+ track2 = (*block)[block->Nentries()-1];
+ }
+ else
+ {
+ // In this case track2 must have the highest pT so ignore the new
+ // track and delete track1.
+ track1 = (*block)[block->Nentries()-1];
+ }
+
+ // Decrement the number of entries because we deleted a track.
+ assert(fTrackCount > 0);
+ assert(block->Nentries() > 0);
+ block->SetNumberOfEntries(block->Nentries()-1);
+ fTrackCount--;
+ }
+ else if (dup1 != block->Nentries())
+ {
+ // Only one track with duplicate hits found.
+ // See if the new track has higher pT. If it does then replace the
+ // exisiting track, otherwise ignore the new track.
+ AliHLTMUONMansoTrackStruct& track1 = (*block)[dup1];
+ double newPt = sqrt(newTrack.fPx * newTrack.fPx + newTrack.fPy * newTrack.fPy);
+ double dupPt1 = sqrt(track1.fPx * track1.fPx + track1.fPy * track1.fPy);
+ if (newPt >= dupPt1)
+ {
+ track1 = newTrack;
+ }
+ }
+ else
+ {
+ // No track found with duplicate hits so we can add the new track as it is.
+ AliHLTMUONMansoTrackStruct* track = block->AddEntry();
+ if (track == NULL)
+ {
+ Logging(kHLTLogError,
+ "AliHLTMUONMansoTrackerFSMComponent::FoundTrack",
+ "Buffer overflow",
+ "We have overflowed the output buffer for Manso track data."
+ " The output buffer size is only %d bytes.",
+ block->BufferSize()
+ );
+ return;
+ }
+
+ fTrackCount++;
+ *track = newTrack;
+ DebugTrace("\tAdded new track: " << *track);
}
-
- fTrackCount++;
- tracker->FillTrackData(*track);
- DebugTrace("\tTrack data = " << *track);
}