]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/BASE/test/testAliHLTComponent.C
moving CTP functionality of the component base class to the AliHLTCTPData class, and
[u/mrichter/AliRoot.git] / HLT / BASE / test / testAliHLTComponent.C
CommitLineData
cf9cf07e 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 testAliHLTComponent_CTPTrigger.C
20 @author Matthias Richter
21 @date
02bc7a5f 22 @brief Test program for the AliHLTComponent base class
cf9cf07e 23 */
24
25#ifndef __CINT__
26#include "TDatime.h"
27#include "TRandom.h"
28#include "AliHLTDataTypes.h"
29#include "AliHLTProcessor.h"
02bc7a5f 30#include "algorithm"
31#include "TObjArray.h"
32#include "TObjString.h"
33#include "TString.h"
cf9cf07e 34#endif
35
02bc7a5f 36using namespace std;
37
cf9cf07e 38class AliHLTTestComponent : public AliHLTProcessor
39{
40public:
02bc7a5f 41 AliHLTTestComponent() :
42 fArguments(),
43 fCurrentArgument(fArguments.begin())
44 {}
45
cf9cf07e 46 ~AliHLTTestComponent() {}
47
48 const char* GetComponentID() {return "TestComponent";};
49 void GetInputDataTypes(AliHLTComponentDataTypeList& list) {list.clear();}
50 AliHLTComponentDataType GetOutputDataType() {return kAliHLTAnyDataType;}
51 void GetOutputDataSize(unsigned long& constBase, double& inputMultiplier) {constBase=0; inputMultiplier=0;}
52 AliHLTComponent* Spawn() {return new AliHLTTestComponent;}
53
02bc7a5f 54 class AliHLTConfigurationArgument {
55 public:
56 AliHLTConfigurationArgument(const char* argument) :
57 fElements(NULL)
58 {
59 TString work=argument;
60 fElements=work.Tokenize(" ");
61 }
62
63 AliHLTConfigurationArgument(const AliHLTConfigurationArgument& src) :
64 fElements(NULL)
65 {
66 if (src.fElements) {
67 fElements=dynamic_cast<TObjArray*>(src.fElements->Clone());
68 }
69 }
70
71 ~AliHLTConfigurationArgument() {
72 if (fElements) delete fElements;
73 }
74
75 AliHLTConfigurationArgument& operator=(const AliHLTConfigurationArgument& src) {
76 delete fElements;
77 if (src.fElements) {
78 fElements=dynamic_cast<TObjArray*>(src.fElements->Clone());
79 }
80 return *this;
81 }
82
83 const char* Argument() {
84 if (!fElements) return NULL;
85 return ((TObjString*)fElements->At(0))->GetString().Data();
86 }
87
88 int NofParameters() {
89 if (!fElements) return 0;
90 return fElements->GetEntriesFast()-1;
91 }
92
93 const char* Parameter(int i) {
94 if (!fElements ||
95 fElements->GetEntriesFast()<=i+1) return NULL;
96 return ((TObjString*)fElements->At(i+1))->GetString().Data();
97 }
98
99 bool operator==(const char* string) {
100 if (!fElements) return 0;
101 return (((TObjString*)fElements->At(0))->GetString().CompareTo(string))==0;
102 }
103
104 bool operator!=(const char* string) {
105 return !operator==(string);
106 }
107
108 void Print() {
109 if (!fElements) {
110 cout << "############# empty ############" << endl;
111 return;
112 }
113 cout << " Print: " << Argument() << " with " << NofParameters() << " parameter(s)";
114 for (int n=0; n<NofParameters(); n++) cout << " " << Parameter(n);
115 cout << endl;
116 }
117
118 private:
119 TObjArray* fElements;
120 };
121
122 int ScanConfigurationArgument(int argc, const char** argv) {
123 if (fCurrentArgument==fArguments.end()) return 0;
124 int count=0;
125
126 // check whether it is an argument at all
127 if (*(argv[count])!='-') {
128 cerr << "not a recognized argument: " << argv[count] << endl;
129 return -EINVAL;
130 }
131
132 // check whether the argument matches
133 //fCurrentArgument->Print();
134 if (*fCurrentArgument!=argv[count]) {
135 cerr << "argument sequence does not match: got " << argv[count] << " expected " << fCurrentArgument->Argument() << endl;
136 return -EINVAL;
137 }
138
139 count++;
140 // read parameters
141 if (fCurrentArgument->NofParameters()>0) {
142 if (argc<=count) {
143 cerr << "missing parameter" << endl;
144 return -EPROTO;
145 }
146
147 // implement more checks here
148 count+=fCurrentArgument->NofParameters();
149 }
150 fCurrentArgument++;
151 return count;
152 }
153
154 int FillArgumentVector(const char** arguments, vector<AliHLTConfigurationArgument>& list) {
155 list.clear();
156 for (const char** iter=arguments; *iter!=NULL; iter++) {
157 list.push_back(AliHLTConfigurationArgument(*iter));
158 }
159 return list.size();
160 }
161
162 int FillArgv(vector<AliHLTConfigurationArgument>& list, vector<const char*>& argv) {
163 argv.clear();
164 for (vector<AliHLTConfigurationArgument>::iterator argument=list.begin();
165 argument!=list.end(); argument++) {
166 argv.push_back(argument->Argument());
167 for (int n=0; n<argument->NofParameters(); n++) {
168 argv.push_back(argument->Parameter(n));
169 }
170 }
171 return argv.size();
172 }
173
174 void PrintArgv(int argc, const char** argv) {
175 for (int n=0; n<argc; n++) {
176 cout << " " << n << " : " << argv[n] << endl;
177 }
178 }
179
180 int CheckSequence(const char* sequence[], int mode=0) {
181 int iResult=0;
182 if ((iResult=FillArgumentVector(sequence, fArguments))<0) {
183 cerr << "failed to fill argument vector" << endl;
184 return iResult;
185 }
186 vector<const char*> argv;
187 if (mode==0) {
188 if ((iResult=FillArgv(fArguments, argv))<0) {
189 cerr << "failed to fill argument array" << endl;
190 return iResult;
191 }
192 } else {
193 for (const char** element=sequence; *element!=NULL; element++)
194 argv.push_back(*element);
195 }
196 fCurrentArgument=fArguments.begin();
197 //PrintArgv(argv.size(), &argv[0]);
198 if ((iResult=ConfigureFromArgumentString(argv.size(), &argv[0]))<0) {
199 cerr << "ConfigureFromArgumentString failed " << endl;
200 return iResult;
201 }
202
203 return iResult;
204 }
205
206 int CheckConfigure() {
207 int iResult=0;
208 const char* sequence1[]={"-sequence1","-argument2 5", NULL};
209 if ((iResult=CheckSequence(sequence1))<0) {
210 cerr << "failed checking sequence " << sequence1[0] << endl;
211 return iResult;
212 }
213
214 const char* sequence2[]={"-sequence2","-argument2 5 8", "-argument3 test", NULL};
215 if ((iResult=CheckSequence(sequence2))<0) {
216 cerr << "failed checking sequence in mode 0: " << sequence2[0] << endl;
217 return iResult;
218 }
219
220 if ((iResult=CheckSequence(sequence2, 1))<0) {
221 cerr << "failed checking sequence in mode 1: " << sequence2[0] << endl;
222 return iResult;
223 }
224
225 const char* sequence3[]={"-solenoidBz 5", NULL};
226 if ((iResult=CheckSequence(sequence3))<0) {
227 cerr << "failed checking sequence " << sequence3[0] << endl;
228 return iResult;
229 }
230 return iResult;
231 }
232
233 int InitCTPTest(const char* param) {
234 // this quick test needs to be the functions of the base class to be
235 // defined 'protected'
adb91bc3 236 SetupCTPData();
02bc7a5f 237 //return ScanECSParam(param);
cf9cf07e 238 //return InitCTPTriggerClasses(param);
02bc7a5f 239 return -ENOSYS;
cf9cf07e 240 }
241
02bc7a5f 242 bool CheckCTP(const char* expression, AliHLTComponentTriggerData* data) {
cf9cf07e 243 return EvaluateCTPTriggerClass(expression, *data);
244 }
245
246 class AliHLTCTPTriggerClass {
247 public:
248 AliHLTCTPTriggerClass() : fBit(~(unsigned)0), fClassName(""), fTrigger(false) {}
249 ~AliHLTCTPTriggerClass() {}
250
251 bool Valid() {return fBit!=~(unsigned)0;}
252 unsigned Bit() {return fBit;}
253 void Bit(unsigned bit) {fBit=bit;}
254 bool Trigger() {return fTrigger;}
255 void Trigger(bool trigger) {fTrigger=trigger;}
256 const char* ClassName() {return fClassName.c_str();}
257 void ClassName(const char* classname) {fClassName=classname;}
258 private:
259 unsigned fBit;
260 string fClassName;
261 bool fTrigger;
262 };
263protected:
264 int DoInit(int /*argc*/, const char** /*argv*/) {
adb91bc3 265 SetupCTPData();
cf9cf07e 266 return 0;
267 }
268
269 int DoDeinit() {
270 return 0;
271 }
272
273 int DoEvent( const AliHLTComponentEventData& /*evtData*/,
274 AliHLTComponentTriggerData& /*trigData*/) {
275 return 0;
276 }
02bc7a5f 277private:
278 vector<AliHLTConfigurationArgument> fArguments;
279 vector<AliHLTConfigurationArgument>::iterator fCurrentArgument;
cf9cf07e 280};
281
282class AliHLTTriggerDataAccess
283{
284public:
285 AliHLTTriggerDataAccess()
286 : fData(NULL)
287 , fEventData(NULL)
288 , fCDH(NULL)
289 , fMine(NULL)
290 {
291 unsigned size=sizeof(AliHLTComponentTriggerData) + sizeof(AliHLTEventTriggerData);
292 fMine=new Byte_t[size];
293 memset(fMine, 0, size);
294 AliHLTComponentTriggerData* data=reinterpret_cast<AliHLTComponentTriggerData*>(fMine);
295 data->fData=fMine+sizeof(AliHLTComponentTriggerData);
296 Set(data);
297 }
298
299 AliHLTTriggerDataAccess(AliHLTComponentTriggerData* pData)
300 : fData(NULL)
301 , fEventData(NULL)
302 , fCDH(NULL)
303 , fMine(NULL)
304 {
305 if (fMine) delete [] fMine;
306 fMine=NULL;
307 Set(pData);
308 }
309
310 ~AliHLTTriggerDataAccess(){
311 if (fMine) delete [] fMine;
312 fMine=NULL;
313 fData=NULL;
314 fEventData=NULL;
315 fCDH=NULL;
316 }
317
318 AliHLTComponentTriggerData* Data() {return fData;}
319
320 Long64_t TriggerMask() {
321 Long64_t mask=0;
322 if (fCDH) {
323 mask=fCDH[6];
324 mask<<=32;
325 mask|=fCDH[5];
326 }
327 return mask;
328 }
329
330 int Set(AliHLTComponentTriggerData* data) {
331 fData=data;
332 fData->fDataSize=sizeof(AliHLTEventTriggerData);
333 fEventData=reinterpret_cast<AliHLTEventTriggerData*>(fData->fData);
334 fCDH=fEventData->fCommonHeader;
335 return 0;
336 }
337
338 int ResetCDH() {
339 if (fCDH) {
340 memset(fCDH, 0, 32);
341 }
342 return 0;
343 }
344
345 int TriggerBit(unsigned bit, bool set) {
346 if ((int)bit>=gkNCTPTriggerClasses) return -EINVAL;
347 if (!fCDH) return -ENODATA;
348
349 int word=5;
350 if (bit>=32) {
351 word++;
352 bit-=32;
353 }
354 if (set)
355 fCDH[word]|=(UInt_t)0x1<<bit;
356 else
357 fCDH[word]&=~((UInt_t)0x1<<bit);
358
359 return bit;
360 }
361
362private:
363 AliHLTTriggerDataAccess(const AliHLTTriggerDataAccess&);
364 AliHLTTriggerDataAccess& operator=(const AliHLTTriggerDataAccess&);
365
366 AliHLTComponentTriggerData* fData;
367 AliHLTEventTriggerData* fEventData;
368 AliHLTUInt32_t* fCDH;
369 Byte_t* fMine;
370};
371
02bc7a5f 372/////////////////////////////////////////////////////////////////////////
373/////////////////////////////////////////////////////////////////////////
374//
375// setup of the CTP test
376
cf9cf07e 377/**
378 * Get a random number in the given range.
379 */
380int GetRandom(int min, int max)
381{
382 if (max-min<2) return min;
383 static TRandom rand;
384 static bool seedSet=false;
385 if (!seedSet) {
386 TDatime dt;
387 rand.SetSeed(dt.Get());
388 seedSet=true;
389 }
390 return min+rand.Integer(max-min);
391}
392
393/**
394 * Generate a random name of given length
395 */
396string GenerateTriggerClassName(int length)
397{
398 string tcn;
399 for (int i=0; i<length; i++) {
400 unsigned char c=GetRandom(48, 83);
401 if (c>57) c+=7;
402 tcn+=c;
403 }
404 return tcn;
405}
406
407/**
408 * Generate an array of trigger classes.
409 * The array has the specified size but the number antries which are actually
410 * filled is randomized.
411 */
412int GenerateTriggerClasses(int size, vector<AliHLTTestComponent::AliHLTCTPTriggerClass>& classes)
413{
414 classes.clear();
415 classes.resize(size);
416 unsigned count=GetRandom(4, size>16?size/2:size);
417 for (unsigned i=0; i<count; i++) {
418 int bit=0;
419 do {
420 bit=GetRandom(0, size);
421 } while (classes[bit].Valid());
422 classes[bit].Bit(bit);
423 classes[bit].ClassName((GenerateTriggerClassName(GetRandom(5,15))).c_str());
424 }
425 return classes.size();
426}
427
02bc7a5f 428/**
429 * Test the CTP trigger tools
430 * The base class is initialized with an ECS string of randomly defined trigger
431 * classes consisting of random bits and names. Than a couple of expressions is
432 * test for various random bit patterns.
433 */
434int testCTPTrigger()
cf9cf07e 435{
02bc7a5f 436 cout << "checking CTP functionality of the base class" << endl;
cf9cf07e 437 int iResult=0;
438 vector<AliHLTTestComponent::AliHLTCTPTriggerClass> triggerClasses;
439 if (GenerateTriggerClasses(GetRandom(5,gkNCTPTriggerClasses), triggerClasses)<=0) {
440 return -1;
441 }
442
443 TString parameter="CONFIGURE;CTP_TRIGGER_CLASS=";
444 vector<AliHLTTestComponent::AliHLTCTPTriggerClass>::iterator element=triggerClasses.begin();
445 while (element!=triggerClasses.end()) {
446 if (!element->Valid()) {
447 element=triggerClasses.erase(element);
448 continue;
449 }
450 if (!parameter.EndsWith("=")) parameter+=",";
adb91bc3 451 if (element->Bit()<10) parameter+="0";
452 parameter+=element->Bit();
453 parameter+=":";
cf9cf07e 454 parameter+=element->ClassName(); parameter+=":";
adb91bc3 455 parameter+="05-01-06"; // just a test pattern for the detector ids, ignored for the moment
cf9cf07e 456 element++;
457 }
458 parameter+=";HLT_MODE=A;RUN_NO=0";
459
460 AliHLTTestComponent component;
461 component.SetGlobalLoggingLevel(kHLTLogDefault);
02bc7a5f 462 if ((iResult=component.InitCTPTest(parameter.Data()))<0) {
463 cerr << "InitCTPTest failed :" << iResult << endl;
464 return iResult;
465 }
adb91bc3 466 cout << "init ECS parameter: " << parameter << endl;
cf9cf07e 467
468 AliHLTTriggerDataAccess trigData;
469 for (int cycle=0; cycle<500 && iResult>=0; cycle++) {
470 for (element=triggerClasses.begin();
471 element!=triggerClasses.end(); element++) {
472 element->Trigger(GetRandom(0,100)>50);
473 }
474
475 vector<AliHLTTestComponent::AliHLTCTPTriggerClass> shuffle;
476 shuffle.assign(triggerClasses.begin(), triggerClasses.end());
477 for (unsigned int trial=0; trial<2*triggerClasses.size() && iResult>=0; trial++) {
478 random_shuffle(shuffle.begin(), shuffle.end());
479
480 bool result=0;
481 bool trigger=0;
482 TString expression;
483 trigData.ResetCDH();
484 for (element=shuffle.begin();
485 element!=shuffle.end(); element++) {
486 trigData.TriggerBit(element->Bit(), element->Trigger());
487 }
488
489 // single class
490 for (element=shuffle.begin();
491 element!=shuffle.end() && iResult>=0 && trial<3;
492 element++) {
493 // is
494 result=element->Trigger();
495 expression=element->ClassName();
02bc7a5f 496 trigger=component.CheckCTP(expression.Data(), trigData.Data());
cf9cf07e 497 if (trigger!=result) {
498 cout << expression << ": " << element->Trigger()
499 << "->" << trigger
500 << std::hex << " (" << trigData.TriggerMask() << ")"
501 << endl;
502 cerr << "trigger does not match, expected " << result << endl;
503 iResult=-1;
504 break;
505 }
506
507 // is not
508 expression="!";
509 expression+=element->ClassName();
510 result=!result;
02bc7a5f 511 trigger=component.CheckCTP(expression.Data(), trigData.Data());
cf9cf07e 512 if (trigger!=result) {
513 cout << expression << ": " << element->Trigger()
514 << "->" << trigger
515 << std::hex << " (" << trigData.TriggerMask() << ")"
516 << endl;
517 cerr << "trigger does not match, expected " << result << endl;
518 iResult=-1;
519 break;
520 }
521 }
522
523 // OR
524 result=shuffle[0].Trigger() || shuffle[1].Trigger() || shuffle[2].Trigger();
525 expression.Form("%s || %s || %s",
526 shuffle[0].ClassName(), shuffle[1].ClassName(), shuffle[2].ClassName());
02bc7a5f 527 trigger=component.CheckCTP(expression.Data(), trigData.Data());
cf9cf07e 528 if (trigger!=result) {
529 cout << expression << ": " << shuffle[0].Trigger() << shuffle[1].Trigger() << shuffle[2].Trigger()
530 << "->" << trigger
531 << std::hex << " (" << trigData.TriggerMask() << ")"
532 << endl;
533 cerr << "trigger does not match, expected " << result << endl;
534 iResult=-1;
535 break;
536 }
537
538 // AND
539 result=shuffle[0].Trigger() && shuffle[1].Trigger() && shuffle[2].Trigger();
540 expression.Form("%s && %s && %s",
541 shuffle[0].ClassName(), shuffle[1].ClassName(), shuffle[2].ClassName());
542
02bc7a5f 543 trigger=component.CheckCTP(expression.Data(), trigData.Data());
cf9cf07e 544 if (trigger!=result) {
545 cout << expression << ": " << shuffle[0].Trigger() << shuffle[1].Trigger() << shuffle[2].Trigger()
546 << "->" << trigger
547 << std::hex << " (" << trigData.TriggerMask() << ")"
548 << endl;
549 cerr << "trigger does not match, expected " << result << endl;
550 iResult=-1;
551 break;
552 }
553
554 // mixed OR/AND
555 result=shuffle[0].Trigger() && (shuffle[1].Trigger() || shuffle[2].Trigger());
556 expression.Form("%s && (%s || %s)",
557 shuffle[0].ClassName(), shuffle[1].ClassName(), shuffle[2].ClassName());
558
02bc7a5f 559 trigger=component.CheckCTP(expression.Data(), trigData.Data());
cf9cf07e 560 if (trigger!=result) {
561 cout << expression << ": " << shuffle[0].Trigger() << shuffle[1].Trigger() << shuffle[2].Trigger()
562 << "->" << trigger
563 << std::hex << " (" << trigData.TriggerMask() << ")"
564 << endl;
565 cerr << "trigger does not match, expected " << result << endl;
566 iResult=-1;
567 break;
568 }
569 }
570 }
571 if (iResult<0) {
572 cerr << "check failed, dumping info" << endl;
573 cerr << "ECS param: " << parameter << endl;
574 for (element=triggerClasses.begin();
575 element!=triggerClasses.end(); element++) {
576 cerr << element->Trigger() << " " << element->Bit() << ": " << element->ClassName() << endl;
577 }
578 }
579 return iResult;
580}
581
02bc7a5f 582/////////////////////////////////////////////////////////////////////////
583/////////////////////////////////////////////////////////////////////////
584//
585// setup of the Configure test
586int testConfigure()
587{
588 cout << "checking common configuration tools of the base class" << endl;
589 AliHLTTestComponent component;
590 return component.CheckConfigure();
591}
592
593/////////////////////////////////////////////////////////////////////////
594/////////////////////////////////////////////////////////////////////////
595//
596// main functions
597
598int testAliHLTComponent()
599{
600 int iResult=0;
601 //if ((iResult=testCTPTrigger())<0) return iResult;
602 if ((iResult=testConfigure())<0) return iResult;
603 return iResult;
604}
605
cf9cf07e 606int main(int /*argc*/, const char** /*argv*/)
607{
608 int iResult=0;
02bc7a5f 609 iResult=testAliHLTComponent();
cf9cf07e 610 return iResult;
611}