]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/BASE/test/testAliHLTComponent.C
A little task for checking the c*tau of the strange particles
[u/mrichter/AliRoot.git] / HLT / BASE / test / testAliHLTComponent.C
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   
22     @brief  Test program for the AliHLTComponent base class
23  */
24
25 #ifndef __CINT__
26 #include "TDatime.h"
27 #include "TRandom.h"
28 #include "AliHLTDataTypes.h"
29 #include "AliHLTProcessor.h"
30 #include "algorithm"
31 #include "TObjArray.h"
32 #include "TObjString.h"
33 #include "TString.h"
34 #endif
35
36 using namespace std;
37
38 class AliHLTTestComponent : public AliHLTProcessor
39 {
40 public:
41   AliHLTTestComponent() :
42     fArguments(),
43     fCurrentArgument(fArguments.begin())
44   {}
45
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
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'
236     SetupCTPData();
237     //return ScanECSParam(param);
238     //return InitCTPTriggerClasses(param);
239     return -ENOSYS;
240   }
241
242   bool CheckCTP(const char* expression, AliHLTComponentTriggerData* data) {
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   };
263 protected:
264   int DoInit(int /*argc*/, const char** /*argv*/) {
265     SetupCTPData();
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   }
277 private:
278   vector<AliHLTConfigurationArgument> fArguments;
279   vector<AliHLTConfigurationArgument>::iterator fCurrentArgument;
280 };
281
282 class AliHLTTriggerDataAccess
283 {
284 public:
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
362 private:
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
372 /////////////////////////////////////////////////////////////////////////
373 /////////////////////////////////////////////////////////////////////////
374 //
375 // setup of the CTP test
376
377 /**
378  * Get a random number in the given range.
379  */
380 int 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  */
396 string 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  */
412 int 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
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  */
434 int testCTPTrigger()
435 {
436   cout << "checking CTP functionality of the base class" << endl;
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+=",";
451     if (element->Bit()<10) parameter+="0";
452     parameter+=element->Bit(); 
453     parameter+=":";
454     parameter+=element->ClassName(); parameter+=":";
455     parameter+="05-01-06"; // just a test pattern for the detector ids, ignored for the moment
456     element++;
457   }
458   parameter+=";HLT_MODE=A;RUN_NO=0";
459
460   AliHLTTestComponent component;
461   component.SetGlobalLoggingLevel(kHLTLogDefault);
462   if ((iResult=component.InitCTPTest(parameter.Data()))<0) {
463     cerr << "InitCTPTest failed :" << iResult << endl;
464     return iResult;
465   }
466   cout << "init ECS parameter: " << parameter << endl;
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();
496         trigger=component.CheckCTP(expression.Data(), trigData.Data());
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;
511         trigger=component.CheckCTP(expression.Data(), trigData.Data());
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());
527       trigger=component.CheckCTP(expression.Data(), trigData.Data());
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
543       trigger=component.CheckCTP(expression.Data(), trigData.Data());
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
559       trigger=component.CheckCTP(expression.Data(), trigData.Data());
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
582 /////////////////////////////////////////////////////////////////////////
583 /////////////////////////////////////////////////////////////////////////
584 //
585 // setup of the Configure test
586 int 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
598 int 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
606 int main(int /*argc*/, const char** /*argv*/)
607 {
608   int iResult=0;
609   iResult=testAliHLTComponent();
610   return iResult;
611 }