1 /**************************************************************************
2 * This file is property of and copyright by the ALICE HLT Project *
3 * All rights reserved. *
6 * Artur Szostak <artursz@iafrica.com> *
8 * Permission to use, copy, modify and distribute this software and its *
9 * documentation strictly for non-commercial purposes is hereby granted *
10 * without fee, provided that the above copyright notice appears in all *
11 * copies and that both the copyright notice and this permission notice *
12 * appear in the supporting documentation. The authors make no claims *
13 * about the suitability of this software for any purpose. It is *
14 * provided "as is" without express or implied warranty. *
15 **************************************************************************/
20 /// @file AliHLTMUONEmptyEventFilterComponent.cxx
21 /// @author Artur Szostak <artursz@iafrica.com>
23 /// @brief Implementation of the empty event filter component.
25 /// This component is used to forward events for where there is at least one
26 /// non-empty dHLT data block.
29 #include "AliHLTMUONEmptyEventFilterComponent.h"
30 #include "AliHLTMUONRecHitsBlockStruct.h"
31 #include "AliHLTMUONTriggerRecordsBlockStruct.h"
32 #include "AliHLTMUONMansoTracksBlockStruct.h"
33 #include "AliHLTMUONConstants.h"
34 #include "AliHLTLogging.h"
35 #include "AliHLTSystem.h"
36 #include "AliHLTDefinitions.h"
41 ClassImp(AliHLTMUONEmptyEventFilterComponent)
44 AliHLTMUONEmptyEventFilterComponent::AliHLTMUONEmptyEventFilterComponent() :
49 /// Default constructor.
54 AliHLTMUONEmptyEventFilterComponent::~AliHLTMUONEmptyEventFilterComponent()
57 /// Default destructor.
61 const char* AliHLTMUONEmptyEventFilterComponent::GetComponentID()
64 /// Inherited from AliHLTComponent. Returns the component ID.
67 return AliHLTMUONConstants::EmptyEventFilterComponentId();
71 void AliHLTMUONEmptyEventFilterComponent::GetInputDataTypes( std::vector<AliHLTComponentDataType>& list)
74 /// Inherited from AliHLTProcessor. Returns the list of expected input data types.
75 /// At the moment this list is "any data type" since it is not known before
76 /// hand what kind of input blocks we will get.
78 assert( list.empty() );
79 list.push_back( kAliHLTAnyDataType );
83 AliHLTComponentDataType AliHLTMUONEmptyEventFilterComponent::GetOutputDataType()
86 /// Inherited from AliHLTComponent. Returns the output data type of
87 /// "any data type" with MUON origin.
89 return kAliHLTAnyDataType | kAliHLTDataOriginMUON;
93 void AliHLTMUONEmptyEventFilterComponent::GetOutputDataSize(
94 unsigned long& constBase, double& inputMultiplier
98 /// Inherited from AliHLTComponent.
99 /// Returns an estimate of the expected output data size.
101 // Both of these are zero because we will only ever pass on input data blocks
102 // and never generate data in this component.
108 AliHLTComponent* AliHLTMUONEmptyEventFilterComponent::Spawn()
111 /// Inherited from AliHLTComponent. Creates a new object instance.
114 return new AliHLTMUONEmptyEventFilterComponent;
118 int AliHLTMUONEmptyEventFilterComponent::DoInit(int argc, const char** argv)
121 /// Inherited from AliHLTComponent.
122 /// Parses the command line parameters and initialises the component.
125 fSendOnEmpty = false; // Set to the default value.
127 for (int i = 0; i < argc; i++)
129 if (strcmp(argv[i], "-sendempty") == 0)
132 HLTInfo("Turning on anti-filtering. Will be passing all data on empty dHLT results.");
136 HLTError("Unknown option '%s'.", argv[i]);
144 int AliHLTMUONEmptyEventFilterComponent::DoDeinit()
147 /// Inherited from AliHLTComponent. Performs a cleanup of the component.
154 int AliHLTMUONEmptyEventFilterComponent::DoEvent(
155 const AliHLTComponentEventData& evtData,
156 const AliHLTComponentBlockData* blocks,
157 AliHLTComponentTriggerData& /*trigData*/,
158 AliHLTUInt8_t* /*outputPtr*/,
159 AliHLTUInt32_t& size,
160 std::vector<AliHLTComponentBlockData>& outputBlocks
163 /// Inherited from AliHLTProcessor. Processes the new event data.
164 /// Here we go through the list of input data blocks looking for blocks
165 /// containing dHLT results. If all of these blocks are empty then we
166 /// mark the event for filtering.
167 /// What we actually do with the whole event will depend on the fSendOnEmpty
168 /// flag. If it is set to false (the default) then we will copy all the
169 /// input data blocks to output if the dHLT results were NOT empty.
170 /// If fSendOnEmpty is true then we will copy all the input data blocks
171 /// to the output if the dHLT results ARE empty.
173 HLTDebug("Processing event %llu with %u input data blocks.",
174 evtData.fEventID, evtData.fBlockCnt
177 bool emptyEvent = true;
179 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
182 char id[kAliHLTComponentDataTypefIDsize+1];
183 for (int i = 0; i < kAliHLTComponentDataTypefIDsize; i++)
184 id[i] = blocks[n].fDataType.fID[i];
185 id[kAliHLTComponentDataTypefIDsize] = '\0';
186 char origin[kAliHLTComponentDataTypefOriginSize+1];
187 for (int i = 0; i < kAliHLTComponentDataTypefOriginSize; i++)
188 origin[i] = blocks[n].fDataType.fOrigin[i];
189 origin[kAliHLTComponentDataTypefOriginSize] = '\0';
191 HLTDebug("Handling block: %u, with fDataType.fID = '%s',"
192 " fDataType.fID = '%s', fPtr = %p and fSize = %u bytes.",
193 n, static_cast<char*>(id), static_cast<char*>(origin),
194 blocks[n].fPtr, blocks[n].fSize
197 if (blocks[n].fDataType == AliHLTMUONConstants::TriggerRecordsBlockDataType())
199 AliHLTMUONTriggerRecordsBlockReader inblock(blocks[n].fPtr, blocks[n].fSize);
200 if (not BlockStructureOk(inblock, blocks[n].fSize)) continue;
201 if (inblock.Nentries() != 0) emptyEvent = false;
203 else if (blocks[n].fDataType == AliHLTMUONConstants::RecHitsBlockDataType())
205 AliHLTMUONRecHitsBlockReader inblock(blocks[n].fPtr, blocks[n].fSize);
206 if (not BlockStructureOk(inblock, blocks[n].fSize)) continue;
207 if (inblock.Nentries() != 0) emptyEvent = false;
209 else if (blocks[n].fDataType == AliHLTMUONConstants::MansoTracksBlockDataType())
211 AliHLTMUONMansoTracksBlockReader inblock(blocks[n].fPtr, blocks[n].fSize);
212 if (not BlockStructureOk(inblock, blocks[n].fSize)) continue;
213 if (inblock.Nentries() != 0) emptyEvent = false;
215 else if (blocks[n].fDataType == AliHLTMUONConstants::SinglesDecisionBlockDataType())
217 AliHLTMUONSinglesDecisionBlockReader inblock(blocks[n].fPtr, blocks[n].fSize);
218 if (not BlockStructureOk(inblock, blocks[n].fSize)) continue;
219 if (inblock.Nentries() != 0) emptyEvent = false;
221 else if (blocks[n].fDataType == AliHLTMUONConstants::PairsDecisionBlockDataType())
223 AliHLTMUONPairsDecisionBlockReader inblock(blocks[n].fPtr, blocks[n].fSize);
224 if (not BlockStructureOk(inblock, blocks[n].fSize)) continue;
225 if (inblock.Nentries() != 0) emptyEvent = false;
229 // If we are filtering or required to send only empty events then
230 // copy all the input blocks to the output.
231 if (emptyEvent and fSendOnEmpty or not emptyEvent and not fSendOnEmpty)
233 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
235 outputBlocks.push_back(blocks[n]);
239 // Finally we set the total size of output memory we consumed which is
240 // zero since we just copied the input descriptors to output if anything.
246 template <class BlockType>
247 bool AliHLTMUONEmptyEventFilterComponent::BlockStructureOk(
248 const BlockType& inblock,
249 const char* blockName,
250 AliHLTUInt32_t blockBufferSize
253 /// Performs basic checks to see if the input data block structure is OK,
254 /// that is that it is not corrupt, too short etc...
256 if (not inblock.BufferSizeOk())
258 size_t headerSize = sizeof(typename BlockType::HeaderType);
259 if (blockBufferSize < headerSize)
261 HLTError("Received a %s data block with a size of %d bytes,"
262 " which is smaller than the minimum valid header size of %d bytes."
263 " The block must be corrupt.",
264 blockName, blockBufferSize, headerSize
269 size_t expectedWidth = sizeof(typename BlockType::ElementType);
270 if (inblock.CommonBlockHeader().fRecordWidth != expectedWidth)
272 HLTError("Received a %s data block with a record"
273 " width of %d bytes, but the expected value is %d bytes."
274 " The block might be corrupt.",
276 inblock.CommonBlockHeader().fRecordWidth,
282 HLTError("Received a %s data block with a size of %d bytes,"
283 " but the block header claims the block should be %d bytes."
284 " The block might be corrupt.",
285 blockName, blockBufferSize, inblock.BytesUsed()