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