BlockFilter component added; minor corrections
[u/mrichter/AliRoot.git] / HLT / BASE / util / AliHLTBlockFilterComponent.cxx
1 // @(#) $Id$
2
3 /**************************************************************************
4  * This file is property of and copyright by the ALICE HLT Project        * 
5  * ALICE Experiment at CERN, All rights reserved.                         *
6  *                                                                        *
7  * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
8  *                  for The ALICE HLT Project.                            *
9  *                                                                        *
10  * Permission to use, copy, modify and distribute this software and its   *
11  * documentation strictly for non-commercial purposes is hereby granted   *
12  * without fee, provided that the above copyright notice appears in all   *
13  * copies and that both the copyright notice and this permission notice   *
14  * appear in the supporting documentation. The authors make no claims     *
15  * about the suitability of this software for any purpose. It is          *
16  * provided "as is" without express or implied warranty.                  *
17  **************************************************************************/
18
19 /** @file   AliHLTBlockFilterComponent.cxx
20     @author Matthias Richter
21     @date   
22     @brief  A simple data block filter and merger, merges block descriptors
23
24                                                                           */
25 // see header file for class documentation
26 // or
27 // refer to README to build package
28 // or
29 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
30
31 #include <cstdlib>
32 #include "AliHLTBlockFilterComponent.h"
33 #include "TString.h"
34
35 /** ROOT macro for the implementation of ROOT specific class methods */
36 ClassImp(AliHLTBlockFilterComponent)
37
38 AliHLTBlockFilterComponent::AliHLTBlockFilterComponent()
39 {
40   // see header file for class documentation
41   // or
42   // refer to README to build package
43   // or
44   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
45 }
46
47 AliHLTBlockFilterComponent::~AliHLTBlockFilterComponent()
48 {
49   // see header file for class documentation
50 }
51
52 void AliHLTBlockFilterComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list)
53 {
54   // see header file for class documentation
55   list.clear();
56   list.push_back(kAliHLTAnyDataType);
57 }
58
59 AliHLTComponentDataType AliHLTBlockFilterComponent::GetOutputDataType()
60 {
61   // see header file for class documentation
62   if (fFilterRules.size()==1) return fFilterRules[0].fDataType;
63   if (fFilterRules.size()==0) return kAliHLTVoidDataType;
64   return kAliHLTMultipleDataType;
65 }
66
67 int AliHLTBlockFilterComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList)
68 {
69   // see header file for class documentation
70   tgtList.clear();
71   AliHLTComponentBlockDataList::iterator desc=fFilterRules.begin();
72   while (desc!=fFilterRules.end()) {
73     AliHLTComponentDataTypeList::iterator type=tgtList.begin();
74     while (type!=tgtList.end()) {
75       if (*type==(*desc).fDataType) break;
76       type++;
77     }
78     if (type==tgtList.end()) tgtList.push_back((*desc).fDataType);
79     desc++;
80   }
81   return tgtList.size();
82 }
83
84 void AliHLTBlockFilterComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
85 {
86   // see header file for class documentation
87   constBase=0;
88   inputMultiplier=0.0; // there is no new data, just forwarded descriptors
89 }
90
91 int AliHLTBlockFilterComponent::DoInit( int argc, const char** argv )
92 {
93   int iResult=0;
94   TString argument="";
95   int bMissingParam=0;
96   AliHLTComponentBlockData rule;
97   FillBlockData(rule);
98   for (int i=0; i<argc && iResult>=0; i++) {
99     argument=argv[i];
100     if (argument.IsNull()) continue;
101
102     // -datatype
103     if (argument.CompareTo("-datatype")==0) {
104       if ((bMissingParam=(i+2>=argc))) break;
105
106       if (rule.fDataType!=kAliHLTAnyDataType) {
107         // the data type has already been set, add to list
108         // and reset
109         fFilterRules.push_back(rule);
110         FillBlockData(rule);
111       }
112
113       SetDataType(rule.fDataType, argv[i+1], argv[i+2]);
114       i+=2;
115
116       // -dataspec
117     } else if (argument.CompareTo("-dataspec")==0) {
118       if ((bMissingParam=(++i>=argc))) break;
119
120       if (rule.fSpecification!=kAliHLTVoidDataSpec) {
121         // the specification has already been set, add to list
122         // and reset
123         fFilterRules.push_back(rule);
124         FillBlockData(rule);
125       }
126
127       TString parameter(argv[i]);
128       parameter.Remove(TString::kLeading, ' '); // remove all blanks
129       char* pRemnant=NULL;
130       rule.fSpecification=strtoul(parameter.Data(), &pRemnant, 0);
131       if (pRemnant!=NULL && pRemnant[0]!=0) {
132         HLTError("invalid parameter/remnant (%s) for argument %s, number expected", pRemnant, argument.Data());
133         iResult=-EINVAL;
134       }
135     } else {
136       HLTError("unknown argument %s", argument.Data());
137       iResult=-EINVAL;
138       break;
139     }
140   }
141   if (iResult>=0 && (rule.fSpecification!=kAliHLTVoidDataSpec || rule.fDataType!=kAliHLTAnyDataType)) {
142     // add the pending rule
143     fFilterRules.push_back(rule);
144     FillBlockData(rule);
145   }
146   return iResult;
147 }
148
149 int AliHLTBlockFilterComponent::DoDeinit()
150 {
151   int iResult=0;
152   fFilterRules.clear();
153   return iResult;
154 }
155
156 int AliHLTBlockFilterComponent::DoEvent( const AliHLTComponentEventData& evtData,
157                                          const AliHLTComponentBlockData* blocks, 
158                                          AliHLTComponentTriggerData& /*trigData*/,
159                                          AliHLTUInt8_t* /*outputPtr*/, 
160                                          AliHLTUInt32_t& size,
161                                          AliHLTComponentBlockDataList& outputBlocks )
162 {
163   // see header file for class documentation
164   int iResult=0;
165   for (int n=0; n<(int)evtData.fBlockCnt; n++ ) {
166     if (IsSelected(blocks[n])) {
167       HLTDebug("block %d type %s %#x (ptr=%p offset=%d size=%d) selected by filter rules", 
168                n, DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification, 
169                blocks[n].fPtr, blocks[n].fOffset, blocks[n].fSize);
170       outputBlocks.push_back(blocks[n]);
171     } else {
172       HLTDebug("block %d type %s %#x discarded by filter rules", n, DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification);
173     }
174   }
175   size=0;
176   return iResult;
177 }
178
179 int AliHLTBlockFilterComponent::IsSelected(const AliHLTComponentBlockData& block)
180 {
181   // see header file for class documentation
182   AliHLTComponentBlockDataList::iterator desc=fFilterRules.begin();
183   //HLTDebug("check block: %s spec %#x", DataType2Text(block.fDataType, 1).c_str(), block.fSpecification);
184   if (desc==fFilterRules.end()) return 1; // no filter rules
185   do {
186     // match if
187     // 1. data types match or filter data type not set
188     // 2. data spec match or filter data wpec not set
189     // 3. either filter data type or spec is set
190     //HLTDebug("check rule : %s spec %#x", DataType2Text((*desc).fDataType, 2).c_str(), block.fSpecification);
191     if (((*desc).fDataType==block.fDataType || (*desc).fDataType==kAliHLTAnyDataType) &&
192         ((*desc).fSpecification==block.fSpecification || (*desc).fSpecification==kAliHLTVoidDataSpec) &&
193         ((*desc).fDataType!=kAliHLTAnyDataType || (*desc).fSpecification!=kAliHLTVoidDataSpec)) {
194       return 1;
195     }
196   } while (++desc!=fFilterRules.end());
197   
198   return 0;
199 }