]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/MUON/utils/AliHLTMUONEmptyEventFilterComponent.cxx
Updating documentation.
[u/mrichter/AliRoot.git] / HLT / MUON / utils / AliHLTMUONEmptyEventFilterComponent.cxx
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  *                                                                        *
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  **************************************************************************/
16
17 /* $Id$ */
18
19 ///
20 /// @file   AliHLTMUONEmptyEventFilterComponent.cxx
21 /// @author Artur Szostak <artursz@iafrica.com>
22 /// @date   2007-12-12
23 /// @brief  Implementation of the empty event filter component.
24 ///
25 /// This component is used to forward events for where there is at least one
26 /// non-empty dHLT data block.
27 ///
28
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"
37 #include <cstdlib>
38 #include <cerrno>
39 #include <cassert>
40
41 ClassImp(AliHLTMUONEmptyEventFilterComponent)
42
43
44 AliHLTMUONEmptyEventFilterComponent::AliHLTMUONEmptyEventFilterComponent() :
45         AliHLTProcessor(),
46         fSendOnEmpty(false)
47 {
48         ///
49         /// Default constructor.
50         ///
51 }
52
53
54 AliHLTMUONEmptyEventFilterComponent::~AliHLTMUONEmptyEventFilterComponent()
55 {
56         ///
57         /// Default destructor.
58         ///
59 }
60
61 const char* AliHLTMUONEmptyEventFilterComponent::GetComponentID()
62 {
63         ///
64         /// Inherited from AliHLTComponent. Returns the component ID.
65         ///
66         
67         return AliHLTMUONConstants::EmptyEventFilterComponentId();
68 }
69
70
71 void AliHLTMUONEmptyEventFilterComponent::GetInputDataTypes( std::vector<AliHLTComponentDataType>& list)
72 {
73         ///
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.
77         
78         assert( list.empty() );
79         list.push_back( kAliHLTAnyDataType );
80 }
81
82
83 AliHLTComponentDataType AliHLTMUONEmptyEventFilterComponent::GetOutputDataType()
84 {
85         ///
86         /// Inherited from AliHLTComponent. Returns the output data type of
87         /// "any data type" with MUON origin.
88         
89         return kAliHLTAnyDataType | kAliHLTDataOriginMUON;
90 }
91
92
93 void AliHLTMUONEmptyEventFilterComponent::GetOutputDataSize(
94                 unsigned long& constBase, double& inputMultiplier
95         )
96 {
97         ///
98         /// Inherited from AliHLTComponent.
99         /// Returns an estimate of the expected output data size.
100         
101         // Both of these are zero because we will only ever pass on input data blocks
102         // and never generate data in this component.
103         constBase = 0;
104         inputMultiplier = 0;
105 }
106
107
108 AliHLTComponent* AliHLTMUONEmptyEventFilterComponent::Spawn()
109 {
110         ///
111         /// Inherited from AliHLTComponent. Creates a new object instance.
112         ///
113         
114         return new AliHLTMUONEmptyEventFilterComponent;
115 }
116
117
118 int AliHLTMUONEmptyEventFilterComponent::DoInit(int argc, const char** argv)
119 {
120         ///
121         /// Inherited from AliHLTComponent.
122         /// Parses the command line parameters and initialises the component.
123         ///
124
125         fSendOnEmpty = false;  // Set to the default value.
126
127         for (int i = 0; i < argc; i++)
128         {
129                 if (strcmp(argv[i], "-sendempty") == 0)
130                 {
131                         fSendOnEmpty = true;
132                         HLTInfo("Turning on anti-filtering. Will be passing all data on empty dHLT results.");
133                         continue;
134                 }
135                 
136                 HLTError("Unknown option '%s'.", argv[i]);
137                 return EINVAL;
138         }
139
140         return 0;
141 }
142
143
144 int AliHLTMUONEmptyEventFilterComponent::DoDeinit()
145 {
146         ///
147         /// Inherited from AliHLTComponent. Performs a cleanup of the component.
148         ///
149   
150         return 0;
151 }
152
153
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
161         )
162 {
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.
172         
173         HLTDebug("Processing event %llu with %u input data blocks.",
174                 evtData.fEventID, evtData.fBlockCnt
175         );
176
177         bool emptyEvent = true;
178
179         for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
180         {
181 #ifdef __DEBUG
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';
190 #endif // __DEBUG
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
195                 );
196
197                 if (blocks[n].fDataType == AliHLTMUONConstants::TriggerRecordsBlockDataType())
198                 {
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;
202                 }
203                 else if (blocks[n].fDataType == AliHLTMUONConstants::RecHitsBlockDataType())
204                 {
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;
208                 }
209                 else if (blocks[n].fDataType == AliHLTMUONConstants::MansoTracksBlockDataType())
210                 {
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;
214                 }
215                 else if (blocks[n].fDataType == AliHLTMUONConstants::SinglesDecisionBlockDataType())
216                 {
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;
220                 }
221                 else if (blocks[n].fDataType == AliHLTMUONConstants::PairsDecisionBlockDataType())
222                 {
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;
226                 }
227         }
228
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)
232         {
233                 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
234                 {
235                         outputBlocks.push_back(blocks[n]);
236                 }
237         }
238
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.
241         size = 0;
242         return 0;
243 }
244
245
246 template <class BlockType>
247 bool AliHLTMUONEmptyEventFilterComponent::BlockStructureOk(
248                 const BlockType& inblock,
249                 const char* blockName,
250                 AliHLTUInt32_t blockBufferSize
251         ) const
252 {
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...
255
256         if (not inblock.BufferSizeOk())
257         {
258                 size_t headerSize = sizeof(typename BlockType::HeaderType);
259                 if (blockBufferSize < headerSize)
260                 {
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
265                         );
266                         return false;
267                 }
268                 
269                 size_t expectedWidth = sizeof(typename BlockType::ElementType);
270                 if (inblock.CommonBlockHeader().fRecordWidth != expectedWidth)
271                 {
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.",
275                                 blockName,
276                                 inblock.CommonBlockHeader().fRecordWidth,
277                                 expectedWidth
278                         );
279                         return false;
280                 }
281                 
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()
286                 );
287                 return false;
288         }
289
290         return true;
291 }
292