3 /**************************************************************************
4 * This file is property of and copyright by the ALICE HLT Project *
5 * ALICE Experiment at CERN, All rights reserved. *
7 * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8 * for The ALICE HLT Project. *
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 **************************************************************************/
19 /** @file testAliHLTComponent_CTPTrigger.C
20 @author Matthias Richter
22 @brief Test program for the AliHLTComponent base class
28 #include "AliHLTDataTypes.h"
29 #include "AliHLTProcessor.h"
31 #include "TObjArray.h"
32 #include "TObjString.h"
38 class AliHLTTestComponent : public AliHLTProcessor
41 AliHLTTestComponent() :
43 fCurrentArgument(fArguments.begin())
46 ~AliHLTTestComponent() {}
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;}
54 class AliHLTConfigurationArgument {
56 AliHLTConfigurationArgument(const char* argument) :
59 TString work=argument;
60 fElements=work.Tokenize(" ");
63 AliHLTConfigurationArgument(const AliHLTConfigurationArgument& src) :
67 fElements=dynamic_cast<TObjArray*>(src.fElements->Clone());
71 ~AliHLTConfigurationArgument() {
72 if (fElements) delete fElements;
75 AliHLTConfigurationArgument& operator=(const AliHLTConfigurationArgument& src) {
78 fElements=dynamic_cast<TObjArray*>(src.fElements->Clone());
83 const char* Argument() {
84 if (!fElements) return NULL;
85 return ((TObjString*)fElements->At(0))->GetString().Data();
89 if (!fElements) return 0;
90 return fElements->GetEntriesFast()-1;
93 const char* Parameter(int i) {
95 fElements->GetEntriesFast()<=i+1) return NULL;
96 return ((TObjString*)fElements->At(i+1))->GetString().Data();
99 bool operator==(const char* string) {
100 if (!fElements) return 0;
101 return (((TObjString*)fElements->At(0))->GetString().CompareTo(string))==0;
104 bool operator!=(const char* string) {
105 return !operator==(string);
110 cout << "############# empty ############" << endl;
113 cout << " Print: " << Argument() << " with " << NofParameters() << " parameter(s)";
114 for (int n=0; n<NofParameters(); n++) cout << " " << Parameter(n);
119 TObjArray* fElements;
122 int ScanConfigurationArgument(int argc, const char** argv) {
123 if (fCurrentArgument==fArguments.end()) return 0;
126 // check whether it is an argument at all
127 if (*(argv[count])!='-') {
128 cerr << "not a recognized argument: " << argv[count] << endl;
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;
141 if (fCurrentArgument->NofParameters()>0) {
143 cerr << "missing parameter" << endl;
147 // implement more checks here
148 count+=fCurrentArgument->NofParameters();
154 int FillArgumentVector(const char** arguments, vector<AliHLTConfigurationArgument>& list) {
156 for (const char** iter=arguments; *iter!=NULL; iter++) {
157 list.push_back(AliHLTConfigurationArgument(*iter));
162 int FillArgv(vector<AliHLTConfigurationArgument>& list, vector<const char*>& argv) {
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));
174 void PrintArgv(int argc, const char** argv) {
175 for (int n=0; n<argc; n++) {
176 cout << " " << n << " : " << argv[n] << endl;
180 int CheckSequence(const char* sequence[], int mode=0) {
182 if ((iResult=FillArgumentVector(sequence, fArguments))<0) {
183 cerr << "failed to fill argument vector" << endl;
186 vector<const char*> argv;
188 if ((iResult=FillArgv(fArguments, argv))<0) {
189 cerr << "failed to fill argument array" << endl;
193 for (const char** element=sequence; *element!=NULL; element++)
194 argv.push_back(*element);
196 fCurrentArgument=fArguments.begin();
197 //PrintArgv(argv.size(), &argv[0]);
198 if ((iResult=ConfigureFromArgumentString(argv.size(), &argv[0]))<0) {
199 cerr << "ConfigureFromArgumentString failed " << endl;
206 int CheckConfigure() {
208 const char* sequence1[]={"-sequence1","-argument2 5", NULL};
209 if ((iResult=CheckSequence(sequence1))<0) {
210 cerr << "failed checking sequence " << sequence1[0] << endl;
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;
220 if ((iResult=CheckSequence(sequence2, 1))<0) {
221 cerr << "failed checking sequence in mode 1: " << sequence2[0] << endl;
225 const char* sequence3[]={"-solenoidBz 5", NULL};
226 if ((iResult=CheckSequence(sequence3))<0) {
227 cerr << "failed checking sequence " << sequence3[0] << endl;
233 int InitCTPTest(const char* param) {
234 // this quick test needs to be the functions of the base class to be
235 // defined 'protected'
237 //return ScanECSParam(param);
238 //return InitCTPTriggerClasses(param);
242 bool CheckCTP(const char* expression, AliHLTComponentTriggerData* data) {
243 return EvaluateCTPTriggerClass(expression, *data);
246 class AliHLTCTPTriggerClass {
248 AliHLTCTPTriggerClass() : fBit(~(unsigned)0), fClassName(""), fTrigger(false) {}
249 ~AliHLTCTPTriggerClass() {}
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;}
264 int DoInit(int /*argc*/, const char** /*argv*/) {
273 int DoEvent( const AliHLTComponentEventData& /*evtData*/,
274 AliHLTComponentTriggerData& /*trigData*/) {
278 vector<AliHLTConfigurationArgument> fArguments;
279 vector<AliHLTConfigurationArgument>::iterator fCurrentArgument;
282 class AliHLTTriggerDataAccess
285 AliHLTTriggerDataAccess()
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);
299 AliHLTTriggerDataAccess(AliHLTComponentTriggerData* pData)
305 if (fMine) delete [] fMine;
310 ~AliHLTTriggerDataAccess(){
311 if (fMine) delete [] fMine;
318 AliHLTComponentTriggerData* Data() {return fData;}
320 Long64_t TriggerMask() {
330 int Set(AliHLTComponentTriggerData* data) {
332 fData->fDataSize=sizeof(AliHLTEventTriggerData);
333 fEventData=reinterpret_cast<AliHLTEventTriggerData*>(fData->fData);
334 fCDH=fEventData->fCommonHeader;
345 int TriggerBit(unsigned bit, bool set) {
346 if ((int)bit>=gkNCTPTriggerClasses) return -EINVAL;
347 if (!fCDH) return -ENODATA;
355 fCDH[word]|=(UInt_t)0x1<<bit;
357 fCDH[word]&=~((UInt_t)0x1<<bit);
363 AliHLTTriggerDataAccess(const AliHLTTriggerDataAccess&);
364 AliHLTTriggerDataAccess& operator=(const AliHLTTriggerDataAccess&);
366 AliHLTComponentTriggerData* fData;
367 AliHLTEventTriggerData* fEventData;
368 AliHLTUInt32_t* fCDH;
372 /////////////////////////////////////////////////////////////////////////
373 /////////////////////////////////////////////////////////////////////////
375 // setup of the CTP test
378 * Get a random number in the given range.
380 int GetRandom(int min, int max)
382 if (max-min<2) return min;
384 static bool seedSet=false;
387 rand.SetSeed(dt.Get());
390 return min+rand.Integer(max-min);
394 * Generate a random name of given length
396 string GenerateTriggerClassName(int length)
399 for (int i=0; i<length; i++) {
400 unsigned char c=GetRandom(48, 83);
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.
412 int GenerateTriggerClasses(int size, vector<AliHLTTestComponent::AliHLTCTPTriggerClass>& classes)
415 classes.resize(size);
416 unsigned count=GetRandom(4, size>16?size/2:size);
417 for (unsigned i=0; i<count; i++) {
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());
425 return classes.size();
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.
436 cout << "checking CTP functionality of the base class" << endl;
438 vector<AliHLTTestComponent::AliHLTCTPTriggerClass> triggerClasses;
439 if (GenerateTriggerClasses(GetRandom(5,gkNCTPTriggerClasses), triggerClasses)<=0) {
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);
450 if (!parameter.EndsWith("=")) parameter+=",";
451 if (element->Bit()<10) parameter+="0";
452 parameter+=element->Bit();
454 parameter+=element->ClassName(); parameter+=":";
455 parameter+="05-01-06"; // just a test pattern for the detector ids, ignored for the moment
458 parameter+=";HLT_MODE=A;RUN_NO=0";
460 AliHLTTestComponent component;
461 component.SetGlobalLoggingLevel(kHLTLogDefault);
462 if ((iResult=component.InitCTPTest(parameter.Data()))<0) {
463 cerr << "InitCTPTest failed :" << iResult << endl;
466 cout << "init ECS parameter: " << parameter << endl;
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);
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());
484 for (element=shuffle.begin();
485 element!=shuffle.end(); element++) {
486 trigData.TriggerBit(element->Bit(), element->Trigger());
490 for (element=shuffle.begin();
491 element!=shuffle.end() && iResult>=0 && trial<3;
494 result=element->Trigger();
495 expression=element->ClassName();
496 trigger=component.CheckCTP(expression.Data(), trigData.Data());
497 if (trigger!=result) {
498 cout << expression << ": " << element->Trigger()
500 << std::hex << " (" << trigData.TriggerMask() << ")"
502 cerr << "trigger does not match, expected " << result << endl;
509 expression+=element->ClassName();
511 trigger=component.CheckCTP(expression.Data(), trigData.Data());
512 if (trigger!=result) {
513 cout << expression << ": " << element->Trigger()
515 << std::hex << " (" << trigData.TriggerMask() << ")"
517 cerr << "trigger does not match, expected " << result << endl;
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());
527 trigger=component.CheckCTP(expression.Data(), trigData.Data());
528 if (trigger!=result) {
529 cout << expression << ": " << shuffle[0].Trigger() << shuffle[1].Trigger() << shuffle[2].Trigger()
531 << std::hex << " (" << trigData.TriggerMask() << ")"
533 cerr << "trigger does not match, expected " << result << endl;
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());
543 trigger=component.CheckCTP(expression.Data(), trigData.Data());
544 if (trigger!=result) {
545 cout << expression << ": " << shuffle[0].Trigger() << shuffle[1].Trigger() << shuffle[2].Trigger()
547 << std::hex << " (" << trigData.TriggerMask() << ")"
549 cerr << "trigger does not match, expected " << result << endl;
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());
559 trigger=component.CheckCTP(expression.Data(), trigData.Data());
560 if (trigger!=result) {
561 cout << expression << ": " << shuffle[0].Trigger() << shuffle[1].Trigger() << shuffle[2].Trigger()
563 << std::hex << " (" << trigData.TriggerMask() << ")"
565 cerr << "trigger does not match, expected " << result << endl;
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;
582 /////////////////////////////////////////////////////////////////////////
583 /////////////////////////////////////////////////////////////////////////
585 // setup of the Configure test
588 cout << "checking common configuration tools of the base class" << endl;
589 AliHLTTestComponent component;
590 return component.CheckConfigure();
593 /////////////////////////////////////////////////////////////////////////
594 /////////////////////////////////////////////////////////////////////////
598 int testAliHLTComponent()
601 //if ((iResult=testCTPTrigger())<0) return iResult;
602 if ((iResult=testConfigure())<0) return iResult;
606 int main(int /*argc*/, const char** /*argv*/)
609 iResult=testAliHLTComponent();