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