Line data Source code
1 : // $Id$
2 :
3 : //**************************************************************************
4 : //* This file is property of and copyright by the *
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 AliHLTDataGenerator.cxx
20 : /// @author Matthias Richter
21 : /// @date
22 : /// @brief HLT file publisher component implementation.
23 :
24 : #include "AliHLTDataGenerator.h"
25 : #include "TString.h"
26 : #include "TRandom.h"
27 : #include "TDatime.h"
28 :
29 : using namespace std;
30 :
31 : /** ROOT macro for the implementation of ROOT specific class methods */
32 8 : ClassImp(AliHLTDataGenerator)
33 :
34 : AliHLTDataGenerator::AliHLTDataGenerator()
35 : :
36 3 : AliHLTProcessor(),
37 3 : fDataType(kAliHLTVoidDataType),
38 3 : fSpecification(~(AliHLTUInt32_t)0),
39 3 : fSize(0),
40 3 : fRange(0),
41 3 : fCurrSize(0),
42 3 : fDivisor(0),
43 3 : fDecrement(0),
44 3 : fModulo(0),
45 3 : fOffset(0),
46 3 : fMultiplier(1.0)
47 3 : , fpDice(NULL)
48 15 : {
49 : // see header file for class documentation
50 : // or
51 : // refer to README to build package
52 : // or
53 : // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
54 :
55 : // make the lists owners of their objects in order to automatically
56 : // de-allocate the objects
57 6 : }
58 :
59 : AliHLTDataGenerator::~AliHLTDataGenerator()
60 12 : {
61 : // destructor
62 :
63 12 : }
64 :
65 : const char* AliHLTDataGenerator::GetComponentID()
66 : {
67 : // overloaded from AliHLTComponent
68 696 : return "DataGenerator";
69 : }
70 :
71 : void AliHLTDataGenerator::GetInputDataTypes(AliHLTComponentDataTypeList& list)
72 : {
73 : // overloaded from AliHLTComponent
74 0 : list.clear();
75 0 : list.push_back(kAliHLTAnyDataType);
76 0 : }
77 :
78 : AliHLTComponentDataType AliHLTDataGenerator::GetOutputDataType()
79 : {
80 : // overloaded from AliHLTComponent
81 0 : return fDataType;
82 : }
83 :
84 : int AliHLTDataGenerator::GetOutputDataTypes(vector<AliHLTComponentDataType>& tgtList)
85 : {
86 : // overloaded from AliHLTComponent
87 : int count=0;
88 0 : tgtList.clear();
89 0 : tgtList.push_back(fDataType);
90 0 : return count;
91 : }
92 :
93 : void AliHLTDataGenerator::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
94 : {
95 : // overloaded from AliHLTComponent
96 0 : if (fSize>0)
97 0 : constBase=(unsigned long)(fCurrSize+fRange);
98 : else
99 0 : constBase=(unsigned long)(fOffset+fRange);
100 0 : inputMultiplier=fMultiplier;
101 0 : }
102 :
103 : AliHLTComponent* AliHLTDataGenerator::Spawn()
104 : {
105 : // overloaded from AliHLTComponent
106 0 : return new AliHLTDataGenerator;
107 0 : }
108 :
109 : int AliHLTDataGenerator::DoInit( int argc, const char** argv )
110 : {
111 : // overloaded from AliHLTComponent: component initialization
112 :
113 : //HLTDebug("%d %s", argc, argv[0]);
114 : int iResult=0;
115 0 : TString argument="";
116 : int bMissingParam=0;
117 0 : for (int i=0; i<argc && iResult>=0; i++) {
118 0 : argument=argv[i];
119 0 : if (argument.IsNull()) continue;
120 :
121 : // -datatype
122 0 : if (argument.CompareTo("-datatype")==0) {
123 0 : if ((bMissingParam=(++i>=argc))) break;
124 0 : memcpy(&fDataType.fID, argv[i], TMath::Min(kAliHLTComponentDataTypefIDsize, (Int_t)strlen(argv[i])));
125 0 : if ((bMissingParam=(++i>=argc))) break;
126 0 : memcpy(&fDataType.fOrigin, argv[i], TMath::Min(kAliHLTComponentDataTypefOriginSize, (Int_t)strlen(argv[i])));
127 :
128 : // -dataspec
129 0 : } else if (argument.CompareTo("-dataspec")==0) {
130 0 : if ((bMissingParam=(++i>=argc))) break;
131 0 : TString parameter(argv[i]);
132 0 : parameter.Remove(TString::kLeading, ' '); // remove all blanks
133 0 : if (parameter.IsDigit()) {
134 0 : fSpecification=(AliHLTUInt32_t)parameter.Atoi();
135 0 : } else if (parameter.BeginsWith("0x") &&
136 0 : parameter.Replace(0,2,"",0).IsHex()) {
137 0 : sscanf(parameter.Data(),"%x", &fSpecification);
138 : } else {
139 0 : HLTError("wrong parameter for argument %s, number expected", argument.Data());
140 : iResult=-EINVAL;
141 : }
142 : // -size
143 0 : } else if (argument.CompareTo("-size")==0) {
144 0 : if ((bMissingParam=(++i>=argc))) break;
145 0 : if ((iResult=ScanSizeArgument(fSize, argv[i]))==-ERANGE) {
146 0 : HLTError("wrong parameter for argument %s, number expected", argument.Data());
147 : iResult=-EINVAL;
148 0 : }
149 : // -minsize || -maxsize
150 0 : } else if (argument.CompareTo("-minsize")==0 ||
151 0 : argument.CompareTo("-maxsize")==0) {
152 0 : if ((bMissingParam=(++i>=argc))) break;
153 0 : AliHLTUInt32_t value=0;
154 0 : if ((iResult=ScanSizeArgument(value, argv[i]))==-ERANGE) {
155 0 : HLTError("wrong parameter for argument %s, number expected", argument.Data());
156 : iResult=-EINVAL;
157 0 : } else {
158 0 : if (fSize==0) {
159 0 : fSize=value;
160 0 : } else if (fSize<=value) {
161 0 : fRange=value-fSize;
162 0 : fSize=value;
163 0 : } else {
164 0 : fRange=fSize-value;
165 0 : fSize=value;
166 : }
167 : }
168 : // -range
169 0 : } else if (argument.CompareTo("-range")==0) {
170 0 : if ((bMissingParam=(++i>=argc))) break;
171 0 : if ((iResult=ScanSizeArgument(fRange, argv[i]))==-ERANGE) {
172 0 : HLTError("wrong parameter for argument %s, number expected", argument.Data());
173 : iResult=-EINVAL;
174 0 : }
175 : // -divisor
176 0 : } else if (argument.CompareTo("-divisor")==0) {
177 0 : if ((bMissingParam=(++i>=argc))) break;
178 0 : if ((iResult=ScanSizeArgument(fDivisor, argv[i]))==-ERANGE) {
179 0 : HLTError("wrong parameter for argument %s, number expected", argument.Data());
180 : iResult=-EINVAL;
181 0 : }
182 : // -decrement
183 0 : } else if (argument.CompareTo("-decrement")==0) {
184 0 : if ((bMissingParam=(++i>=argc))) break;
185 0 : if ((iResult=ScanSizeArgument(fDecrement, argv[i]))==-ERANGE) {
186 0 : HLTError("wrong parameter for argument %s, number expected", argument.Data());
187 : iResult=-EINVAL;
188 0 : }
189 : // -modulo
190 0 : } else if (argument.CompareTo("-modulo")==0) {
191 0 : if ((bMissingParam=(++i>=argc))) break;
192 0 : if ((iResult=ScanSizeArgument(fModulo, argv[i]))==-ERANGE) {
193 0 : HLTError("wrong parameter for argument %s, number expected", argument.Data());
194 : iResult=-EINVAL;
195 0 : }
196 : // -offset
197 0 : } else if (argument.CompareTo("-offset")==0) {
198 0 : if ((bMissingParam=(++i>=argc))) break;
199 0 : if ((iResult=ScanSizeArgument(fOffset, argv[i]))==-ERANGE) {
200 0 : HLTError("wrong parameter for argument %s, number expected", argument.Data());
201 : iResult=-EINVAL;
202 0 : }
203 : // -multiplier
204 0 : } else if (argument.CompareTo("-multiplier")==0) {
205 0 : if ((bMissingParam=(++i>=argc))) break;
206 0 : if ((iResult=ScanFloatArgument(fMultiplier, argv[i]))==-ERANGE) {
207 0 : HLTError("wrong parameter for argument %s, number expected", argument.Data());
208 : iResult=-EINVAL;
209 0 : }
210 : } else {
211 0 : if ((iResult=ScanArgument(argc-i, &argv[i]))==-EINVAL) {
212 0 : HLTError("unknown argument %s", argument.Data());
213 0 : break;
214 0 : } else if (iResult==-EPROTO) {
215 : bMissingParam=1;
216 0 : break;
217 0 : } else if (iResult>=0) {
218 0 : i+=iResult;
219 : iResult=0;
220 0 : }
221 : }
222 : }
223 :
224 0 : if (bMissingParam) {
225 0 : HLTError("missing parameter for argument %s", argument.Data());
226 : iResult=-EINVAL;
227 0 : }
228 :
229 0 : fCurrSize=fSize;
230 :
231 0 : if (iResult>=0) {
232 0 : fpDice=new TRandom;
233 0 : if (fpDice) {
234 0 : TDatime dt;
235 : // take a component specific property together with the time to
236 : // create a seed
237 0 : const char* chainId=GetChainId();
238 0 : unsigned int seed=CalculateChecksum((const AliHLTUInt8_t*)chainId, strlen(chainId));
239 0 : fpDice->SetSeed(seed^dt.Get());
240 0 : } else {
241 : iResult=-ENOMEM;
242 : }
243 : }
244 :
245 : return iResult;
246 0 : }
247 :
248 : int AliHLTDataGenerator::ScanSizeArgument(AliHLTUInt32_t &size, const char* arg)
249 : {
250 : // helper function to scan an integer argument
251 : // TODO: think about a common framework utility
252 : int iResult=0;
253 0 : if (arg) {
254 0 : TString parameter(arg);
255 : AliHLTUInt32_t base=1;
256 0 : parameter.Remove(TString::kLeading, ' '); // remove all blanks
257 0 : if (parameter.EndsWith("k")) {
258 : base=0x400; // one k
259 0 : parameter.Remove(TString::kTrailing, 'k');
260 0 : } else if (parameter.EndsWith("M")) {
261 : base=0x100000; // one M
262 0 : parameter.Remove(TString::kTrailing, 'M');
263 : }
264 0 : if (parameter.IsDigit()) {
265 0 : size=(AliHLTUInt32_t)parameter.Atoi()*base;
266 0 : } else {
267 : iResult=-ERANGE;
268 : }
269 0 : } else {
270 : iResult=-EINVAL;
271 : }
272 0 : return iResult;
273 0 : }
274 :
275 : int AliHLTDataGenerator::ScanFloatArgument(float &value, const char* arg)
276 : {
277 : // helper function to scan a float argument
278 : // TODO: think about a common framework utility
279 : int iResult=0;
280 0 : if (arg) {
281 0 : TString parameter(arg);
282 0 : parameter.Remove(TString::kLeading, ' '); // remove all blanks
283 0 : if (parameter.IsFloat()) {
284 0 : value=parameter.Atof();
285 0 : } else {
286 : iResult=-ERANGE;
287 : }
288 0 : } else {
289 : iResult=-EINVAL;
290 : }
291 0 : return iResult;
292 0 : }
293 :
294 : int AliHLTDataGenerator::ScanArgument(int argc, const char** argv)
295 : {
296 : // overloaded from AliHLTComponent
297 :
298 : // there are no other arguments than the standard ones
299 0 : if (argc==0 && argv==NULL) {
300 : // this is just to get rid of the warning "unused parameter"
301 : }
302 0 : return -EINVAL;
303 : }
304 :
305 : int AliHLTDataGenerator::DoDeinit()
306 : {
307 : // overloaded from AliHLTComponent: cleanup
308 : int iResult=0;
309 0 : if (fpDice) delete fpDice;
310 0 : fpDice=NULL;
311 :
312 0 : return iResult;
313 : }
314 :
315 : int AliHLTDataGenerator::DoEvent( const AliHLTComponentEventData& evtData,
316 : const AliHLTComponentBlockData* blocks,
317 : AliHLTComponentTriggerData& /*trigData*/,
318 : AliHLTUInt8_t* outputPtr,
319 : AliHLTUInt32_t& size,
320 : AliHLTComponentBlockDataList& outputBlocks )
321 : {
322 : // overloaded from AliHLTProcessor: event processing
323 : int iResult=0;
324 :
325 0 : AliHLTUInt32_t space=size;
326 0 : size=0;
327 0 : if (!IsDataEvent()) return 0;
328 :
329 : AliHLTUInt32_t generated=0;
330 0 : if (fSize>0) {
331 : // mode 1: fake independent of input data size
332 0 : generated=fpDice->Integer(fRange)+fCurrSize;
333 0 : if (fModulo>0 && ((GetEventCount()+1)%fModulo)==0) {
334 : // manipulate the size
335 0 : if (fDivisor>0) {
336 0 : fCurrSize/=fDivisor;
337 0 : if (fCurrSize==0) fCurrSize=fSize; //reset
338 : }
339 0 : if (fDecrement>0) {
340 0 : AliHLTUInt32_t backup=fCurrSize;
341 0 : if (fCurrSize<fDecrement) {
342 0 : fCurrSize=fSize; // reset
343 0 : } else {
344 0 : fCurrSize-=fDecrement;
345 : }
346 : HLTDebug("manipulated output size from %d to %d", backup, fCurrSize);
347 : if (backup==0) {/*just to avoid warning 'unused variable' in the release version*/}
348 0 : }
349 : }
350 :
351 : } else {
352 0 : for (unsigned int i=0; i<evtData.fBlockCnt; i++) {
353 0 : generated+=blocks[i].fSize;
354 : }
355 0 : generated=(AliHLTUInt32_t)(generated*fMultiplier);
356 0 : generated+=fOffset;
357 : }
358 :
359 0 : if (generated<=space ) {
360 : HLTDebug("adding block: size %d", generated);
361 0 : AliHLTComponentBlockData bd;
362 0 : FillBlockData(bd);
363 0 : bd.fPtr=outputPtr;
364 0 : bd.fOffset=0;
365 0 : bd.fSize=generated;
366 0 : bd.fDataType=fDataType;
367 0 : bd.fSpecification=fSpecification;
368 0 : outputBlocks.push_back(bd);
369 0 : size=generated;
370 0 : } else {
371 : iResult=-ENOSPC;
372 : }
373 :
374 : return iResult;
375 0 : }
|