f88cc931b6f8b376e008e801d1223dce1fccd8c5
[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   fFilterRules()
41 {
42   // see header file for class documentation
43   // or
44   // refer to README to build package
45   // or
46   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
47 }
48
49 AliHLTBlockFilterComponent::~AliHLTBlockFilterComponent()
50 {
51   // see header file for class documentation
52 }
53
54 void AliHLTBlockFilterComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list)
55 {
56   // see header file for class documentation
57   list.clear();
58   list.push_back(kAliHLTAnyDataType);
59 }
60
61 AliHLTComponentDataType AliHLTBlockFilterComponent::GetOutputDataType()
62 {
63   // see header file for class documentation
64   if (fFilterRules.size()==1) return fFilterRules[0].fDataType;
65   if (fFilterRules.size()==0) return kAliHLTVoidDataType;
66   return kAliHLTMultipleDataType;
67 }
68
69 int AliHLTBlockFilterComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList)
70 {
71   // see header file for class documentation
72   tgtList.clear();
73   AliHLTComponentBlockDataList::iterator desc=fFilterRules.begin();
74   while (desc!=fFilterRules.end()) {
75     AliHLTComponentDataTypeList::iterator type=tgtList.begin();
76     while (type!=tgtList.end()) {
77       if (*type==(*desc).fDataType) break;
78       type++;
79     }
80     if (type==tgtList.end()) tgtList.push_back((*desc).fDataType);
81     desc++;
82   }
83   return tgtList.size();
84 }
85
86 void AliHLTBlockFilterComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
87 {
88   // see header file for class documentation
89   constBase=0;
90   inputMultiplier=0.0; // there is no new data, just forwarded descriptors
91 }
92
93 int AliHLTBlockFilterComponent::DoInit( int argc, const char** argv )
94 {
95   int iResult=0;
96   TString argument="";
97   int bMissingParam=0;
98   AliHLTComponentBlockData rule;
99   FillBlockData(rule);
100   for (int i=0; i<argc && iResult>=0; i++) {
101     argument=argv[i];
102     if (argument.IsNull()) continue;
103
104     // -datatype
105     if (argument.CompareTo("-datatype")==0) {
106       if ((bMissingParam=(i+2>=argc))) break;
107
108       if (!MatchExactly(rule.fDataType,kAliHLTAnyDataType)) {
109         // the data type has already been set, add to list
110         // and reset
111         fFilterRules.push_back(rule);
112         FillBlockData(rule);
113       }
114
115       SetDataType(rule.fDataType, argv[i+1], argv[i+2]);
116       i+=2;
117
118       // -dataspec
119     } else if (argument.CompareTo("-dataspec")==0) {
120       if ((bMissingParam=(++i>=argc))) break;
121
122       if (rule.fSpecification!=kAliHLTVoidDataSpec) {
123         // the specification has already been set, add to list
124         // and reset
125         fFilterRules.push_back(rule);
126         FillBlockData(rule);
127       }
128
129       TString parameter(argv[i]);
130       parameter.Remove(TString::kLeading, ' '); // remove all blanks
131       char* pRemnant=NULL;
132       rule.fSpecification=strtoul(parameter.Data(), &pRemnant, 0);
133       if (pRemnant!=NULL && pRemnant[0]!=0) {
134         HLTError("invalid parameter/remnant (%s) for argument %s, number expected", pRemnant, argument.Data());
135         iResult=-EINVAL;
136       }
137     } else {
138       HLTError("unknown argument %s", argument.Data());
139       iResult=-EINVAL;
140       break;
141     }
142   }
143   if (iResult>=0 && (rule.fSpecification!=kAliHLTVoidDataSpec || !MatchExactly(rule.fDataType,kAliHLTAnyDataType))) {
144     // add the pending rule
145     fFilterRules.push_back(rule);
146     FillBlockData(rule);
147   }
148   return iResult;
149 }
150
151 int AliHLTBlockFilterComponent::DoDeinit()
152 {
153   int iResult=0;
154   fFilterRules.clear();
155   return iResult;
156 }
157
158 int AliHLTBlockFilterComponent::DoEvent( const AliHLTComponentEventData& evtData,
159                                          const AliHLTComponentBlockData* blocks, 
160                                          AliHLTComponentTriggerData& /*trigData*/,
161                                          AliHLTUInt8_t* /*outputPtr*/, 
162                                          AliHLTUInt32_t& size,
163                                          AliHLTComponentBlockDataList& outputBlocks )
164 {
165   // see header file for class documentation
166   int iResult=0;
167   for (const AliHLTComponentBlockData* pBlock=GetFirstInputBlock();
168        pBlock!=NULL; 
169        pBlock=GetNextInputBlock()) {
170     if (IsSelected(*pBlock)) {
171       HLTDebug("block type %s %#x (ptr=%p offset=%d size=%d) selected by filter rules", 
172                DataType2Text(pBlock->fDataType).c_str(), pBlock->fSpecification, 
173                pBlock->fPtr, pBlock->fOffset, pBlock->fSize);
174       Forward();
175     } else {
176       HLTDebug("block type %s %#x discarded by filter rules", DataType2Text(pBlock->fDataType).c_str(), pBlock->fSpecification);
177     }
178   }
179 //   for (int n=0; n<(int)evtData.fBlockCnt; n++ ) {
180 //     if (IsSelected(blocks[n])) {
181 //       HLTDebug("block %d type %s %#x (ptr=%p offset=%d size=%d) selected by filter rules", 
182 //             n, DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification, 
183 //             blocks[n].fPtr, blocks[n].fOffset, blocks[n].fSize);
184 //       outputBlocks.push_back(blocks[n]);
185 //     } else {
186 //       HLTDebug("block %d type %s %#x discarded by filter rules", n, DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification);
187 //     }
188 //   }
189   size=0;
190   return iResult;
191 }
192
193 int AliHLTBlockFilterComponent::IsSelected(const AliHLTComponentBlockData& block)
194 {
195   // see header file for class documentation
196   AliHLTComponentBlockDataList::iterator desc=fFilterRules.begin();
197   //HLTDebug("check block: %s spec %#x", DataType2Text(block.fDataType, 1).c_str(), block.fSpecification);
198   if (desc==fFilterRules.end()) return 1; // no filter rules
199   do {
200     // match if
201     // 1. data types match or filter data type not set
202     // 2. data spec match or filter data wpec not set
203     // 3. either filter data type or spec is set
204     //HLTDebug("check rule : %s spec %#x", DataType2Text((*desc).fDataType, 2).c_str(), block.fSpecification);
205     if (((*desc).fDataType==block.fDataType) &&
206         ((*desc).fSpecification==block.fSpecification || (*desc).fSpecification==kAliHLTVoidDataSpec) &&
207         (!MatchExactly((*desc).fDataType,kAliHLTAnyDataType) || (*desc).fSpecification!=kAliHLTVoidDataSpec)) {
208       return 1;
209     }
210   } while (++desc!=fFilterRules.end());
211   
212   return 0;
213 }