]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/trigger/test/testTriggerDomain.C
Pileup histograms, asymmetry for pi0 and eta corrected.
[u/mrichter/AliRoot.git] / HLT / trigger / test / testTriggerDomain.C
1 /**************************************************************************
2  * This file is property of and copyright by the ALICE HLT Project        *
3  * ALICE Experiment at CERN, All rights reserved.                         *
4  *                                                                        *
5  * Primary Authors: Artur Szostak <artursz@iafrica.com>                   *
6  *                  for The ALICE HLT Project.                            *
7  *                                                                        *
8  * Permission to use, copy, modify and distribute this software and its   *
9  * documentation strictly for non-commercial purposes is hereby granted   *
10  * without fee, provided that the above copyright notice appears in all   *
11  * copies and that both the copyright notice and this permission notice   *
12  * appear in the supporting documentation. The authors make no claims     *
13  * about the suitability of this software for any purpose. It is          *
14  * provided "as is" without express or implied warranty.                  *
15  **************************************************************************/
16
17 /**
18  * @file   testGlobalTriggerComponent.C
19  * @author Artur Szostak <artursz@iafrica.com>
20  * @date   4 Dec 2008
21  *
22  * This macro is used to test the behaviour of the AliHLTTriggerDomain class.
23  * We specifically check that the AliHLTTriggerDomain operators behave correctly
24  * as set operations.
25  */
26
27 #if defined(__CINT__) && (! defined(__MAKECINT__))
28 #error This macro must be compiled. Try running as testTriggerDomain.C++
29 #endif
30
31 #include "Riostream.h"
32 #include "TSystem.h"
33 #include "TClassTable.h"
34 #include "TRandom3.h"
35 #include "TObjArray.h"
36 #include "AliHLTTriggerDomain.h"
37 #include "AliHLTDomainEntry.h"
38
39 const int N = 6;
40 const char* datatype[N] = {"*******", "AAAAAAAA", "BBBBBBBB", "CCCCCCCC", "DDDDDDDD", "EEEEEEEE"};
41 const char* origin[N] = {"***", "xxxx", "yyyy", "zzzz", "wwww", "uuuu"};
42 int spec[N] = {0, 0x11111111, 0x22222222, 0x33333333, 0x44444444, 0x55555555};
43
44 /**
45  * Randomly builds a trigger domain from the various data types, origins and specifications.
46  * \param [out] domain  The new constructed domain is filled into this output variable.
47  * \param [in]  opcount The number of Add / Remove operations to apply to the domain.
48  */
49 void BuildTriggerDomain(AliHLTTriggerDomain& domain, int opcount = 100)
50 {
51         domain.Clear();
52         for (int i = 0; i < opcount; i++)
53         {
54                 // Make sure not to use the last data type, origin or specification in
55                 // the respective lists because we want to use them later to test the
56                 // matching against wild card values.
57                 int itype = gRandom->Integer(N-1);
58                 int iorigin = gRandom->Integer(N-1);
59                 int ispec = gRandom->Integer(N-1);
60                 if (gRandom->Integer(2) == 0)
61                 {
62                         if (spec[ispec] == 0)
63                                 domain.Add(datatype[itype], origin[iorigin]);
64                         else
65                                 domain.Add(datatype[itype], origin[iorigin], spec[ispec]);
66                 }
67                 else
68                 {
69                         if (spec[ispec] == 0)
70                                 domain.Remove(datatype[itype], origin[iorigin]);
71                         else
72                                 domain.Remove(datatype[itype], origin[iorigin], spec[ispec]);
73                 }
74         }
75 }
76
77 /**
78  * Returns the string representation of the data type.
79  */
80 const char* TypeToString(const AliHLTComponentDataType& type)
81 {
82         static char str[kAliHLTComponentDataTypefIDsize+1];
83         for (int i = 0; i < kAliHLTComponentDataTypefIDsize; i++)
84         {
85                 str[i] = type.fID[i];
86         }
87         return str;
88 }
89
90 /**
91  * Returns the string representation of the data origin.
92  */
93 const char* OriginToString(const AliHLTComponentDataType& type)
94 {
95         static char str[kAliHLTComponentDataTypefOriginSize+1];
96         for (int i = 0; i < kAliHLTComponentDataTypefOriginSize; i++)
97         {
98                 str[i] = type.fOrigin[i];
99         }
100         return str;
101 }
102
103 /**
104  * Checks to see if the domain is correctly constructed compared to the list of entries
105  * that were applied to the domain.
106  * \param [out] entryList The list of entries that were used to construct the domain.
107  * \param [in]  domain    The trigger domain to check.
108  */
109 bool DomainOK(const TObjArray& entryList, const AliHLTTriggerDomain& domain)
110 {
111         for (int i = 1; i < N; i++)
112         for (int j = 1; j < N; j++)
113         for (int k = 1; k < N; k++)
114         {
115                 AliHLTDomainEntry entry(datatype[i], origin[j], spec[k]);
116                 AliHLTComponentBlockData block;
117                 block.fDataType = entry;
118                 block.fSpecification = spec[k];
119                 
120                 bool result = false;
121                 bool result2 = false;
122                 for (int n = 0; n < entryList.GetEntriesFast(); n++)
123                 {
124                         const AliHLTDomainEntry* rule = static_cast<const AliHLTDomainEntry*>( entryList[n] );
125                         if (*rule == entry) result = rule->Inclusive();
126                         if (*rule == &block) result2 = rule->Inclusive();
127                 }
128                 
129                 bool containsResult = domain.Contains(entry);
130                 bool includeResult = domain.IncludeInReadout(&block);
131                 if (containsResult != result or includeResult != result2)
132                 {
133                         cout << "FAILED DomainOK test!" << endl;
134                         cout << "==============================================================================" << endl;
135                         cout << "Dump of how AliHLTTriggerDomain was built:" << endl;
136                         cout << "  AliHLTTriggerDomain domain;" << endl;
137                         for (int n = 0; n < entryList.GetEntriesFast(); n++)
138                         {
139                                 const AliHLTDomainEntry* rule = static_cast<const AliHLTDomainEntry*>( entryList[n] );
140                                 const char* opstr = (rule->Exclusive() ? "Remove" : "Add");
141                                 if (rule->IsValidSpecification())
142                                 {
143                                         cout << "  domain." << opstr << "(\"" << TypeToString(rule->DataType())
144                                                 << "\", \"" << OriginToString(rule->DataType())
145                                                 << "\", 0x" << hex << rule->Specification() << dec
146                                                 << ");" << endl;
147                                 }
148                                 else
149                                 {
150                                         cout << "  domain." << opstr << "(\"" << TypeToString(rule->DataType())
151                                                 << "\", \"" << OriginToString(rule->DataType())
152                                                 << "\");" << endl;
153                                 }
154                         }
155                         cout << "==============================================================================" << endl;
156                         cout << "Dump of the trigger domain contents:" << endl;
157                         domain.Print();
158                         cout << "==============================================================================" << endl;
159                 }
160                 if (containsResult != result)
161                 {
162                         cout << "Failed for entry = ";
163                         entry.Print();
164                         cout << "Result of domain.Contains(entry) == " << containsResult << endl;
165                         cout << " Expected domain.Contains(entry) == " << result << endl;
166                         return false;
167                 }
168                 if (includeResult != result2)
169                 {
170                         cout << "Failed for block: type = " << TypeToString(block.fDataType)
171                                 << ", origin = " << OriginToString(block.fDataType)
172                                 << ", specification = " << hex << block.fSpecification << dec;
173                         cout << "Result of domain.IncludeInReadout(&block) == " << includeResult << endl;
174                         cout << " Expected domain.IncludeInReadout(&block) == " << result2 << endl;
175                         return false;
176                 }
177         }
178         
179         return true;
180 }
181
182 /**
183  * Randomly builds a trigger domain and tests the Add / Remove operations of the
184  * AliHLTTriggerDomain class.
185  * \param [in] opcount The number of Add / Remove operations to use to build the domain.
186  */
187 bool AddRemoveOK(int opcount = 100)
188 {
189         TObjArray entryList;
190         entryList.SetOwner(kTRUE);
191         AliHLTTriggerDomain domain;
192         
193         for (int i = 0; i < opcount; i++)
194         {
195                 // Make sure not to use the last data type, origin or specification in
196                 // the respective lists because we want to use them later to test the
197                 // matching against wild card values.
198                 int itype = gRandom->Integer(N-1);
199                 int iorigin = gRandom->Integer(N-1);
200                 int ispec = gRandom->Integer(N-1);
201                 if (gRandom->Integer(2) == 0)
202                 {
203                         if (spec[ispec] == 0)
204                         {
205                                 entryList.Add(new AliHLTDomainEntry(kFALSE, datatype[itype], origin[iorigin]));
206                                 domain.Add(datatype[itype], origin[iorigin]);
207                         }
208                         else
209                         {
210                                 entryList.Add(new AliHLTDomainEntry(kFALSE, datatype[itype], origin[iorigin], spec[ispec]));
211                                 domain.Add(datatype[itype], origin[iorigin], spec[ispec]);
212                         }
213                 }
214                 else
215                 {
216                         if (spec[ispec] == 0)
217                         {
218                                 entryList.Add(new AliHLTDomainEntry(kTRUE, datatype[itype], origin[iorigin]));
219                                 domain.Remove(datatype[itype], origin[iorigin]);
220                         }
221                         else
222                         {
223                                 entryList.Add(new AliHLTDomainEntry(kTRUE, datatype[itype], origin[iorigin], spec[ispec]));
224                                 domain.Remove(datatype[itype], origin[iorigin], spec[ispec]);
225                         }
226                 }
227         }
228         
229         if (not DomainOK(entryList, domain)) return false;
230         
231         return true;
232 }
233
234
235 #define DefOperation(name, expr, logicExpr) \
236         class name \
237         { \
238         public: \
239                 static const char* Name() \
240                 { \
241                         return #name; \
242                 } \
243                 static const char* Expression() \
244                 { \
245                         return #expr; \
246                 } \
247                 static AliHLTTriggerDomain Apply(const AliHLTTriggerDomain& a, const AliHLTTriggerDomain& b) \
248                 { \
249                         return expr; \
250                 } \
251                 static bool ExpectedResult(bool a, const bool b) \
252                 { \
253                         return logicExpr; \
254                 } \
255         };
256
257
258 DefOperation( OpComplement, ~a,    !a       );
259 DefOperation( OpUnion,      a | b, a | b    );
260 DefOperation( OpIntersect,  a & b, a & b    );
261 DefOperation( OpXor,        a ^ b, a ^ b    );
262 DefOperation( OpDifference,      a - b, a & (!b) );
263
264 /**
265  * Randomly builds two trigger domains and tests a overloaded operator of the
266  * AliHLTTriggerDomain class.
267  * \param [in] opcount The number of Add / Remove operations to use to build the domains.
268  */
269 template <class Op>
270 bool OperatorOK(int opcount = 100)
271 {
272         AliHLTTriggerDomain d1;
273         BuildTriggerDomain(d1, opcount);
274         AliHLTTriggerDomain d2;
275         BuildTriggerDomain(d2, opcount);
276         AliHLTTriggerDomain d3 = Op::Apply(d1, d2);
277         
278         for (int i = 1; i < N; i++)
279         for (int j = 1; j < N; j++)
280         for (int k = 1; k < N; k++)
281         {
282                 AliHLTDomainEntry entry(datatype[i], origin[j], spec[k]);
283                 bool d1Result = d1.Contains(entry);
284                 bool d2Result = d2.Contains(entry);
285                 bool d3Result = d3.Contains(entry);
286                 bool d3ExpectedResult = Op::ExpectedResult(d1Result, d2Result);
287                 if (d3Result != d3ExpectedResult)
288                 {
289                         cout << "FAILED OperatorOK<" << Op::Name() << "> test!" << endl;
290                         cout << "==============================================================================" << endl;
291                         cout << "Dump of the trigger domain a contents:" << endl;
292                         d1.Print();
293                         cout << "==============================================================================" << endl;
294                         cout << "Dump of the trigger domain b contents:" << endl;
295                         d2.Print();
296                         cout << "==============================================================================" << endl;
297                         cout << "Dump of the trigger domain c = " << Op::Expression() << " contents:" << endl;
298                         d3.Print();
299                         cout << "==============================================================================" << endl;
300                         cout << "Failed for entry = ";
301                         entry.Print();
302                         cout << "Result of c.Contains(entry) == " << d3Result << endl;
303                         cout << " Expected c.Contains(entry) == " << d3ExpectedResult << endl;
304                         return false;
305                 }
306         }
307         
308         return true;
309 }
310
311
312 #define DefEqualExprCheck(name, expr1, expr2) \
313         class name \
314         { \
315         public: \
316                 static const char* Name() \
317                 { \
318                         return #name; \
319                 } \
320                 static const char* Expr1() \
321                 { \
322                         return #expr1; \
323                 } \
324                 static const char* Expr2() \
325                 { \
326                         return #expr2; \
327                 } \
328                 static AliHLTTriggerDomain Apply1(const AliHLTTriggerDomain& a, const AliHLTTriggerDomain& b) \
329                 { \
330                         return expr1; \
331                 } \
332                 static AliHLTTriggerDomain Apply2(const AliHLTTriggerDomain& a, const AliHLTTriggerDomain& b) \
333                 { \
334                         return expr2; \
335                 } \
336         };
337
338
339 DefEqualExprCheck( XorExprCheck1,  a ^ b, (a | b) - (a & b)             );
340 DefEqualExprCheck( XorExprCheck2,  a ^ b, (a - (a & b)) | (b - (a & b)) );
341 DefEqualExprCheck( MinusExprCheck1, a - b, a & (a ^ b)                  );
342 DefEqualExprCheck( MinusExprCheck2, a - b, a & ~(a & b)                 );
343
344 /**
345  * Randomly builds two trigger domains and tests two expressions applied to the
346  * domains that should be equivalent.
347  * \param [in] opcount The number of Add / Remove operations to use to build the domains.
348  */
349 template <class Expr>
350 bool EquivalentExpressionsOK(int opcount = 100)
351 {
352         AliHLTTriggerDomain d1;
353         BuildTriggerDomain(d1, opcount);
354         AliHLTTriggerDomain d2;
355         BuildTriggerDomain(d2, opcount);
356         AliHLTTriggerDomain d3 = Expr::Apply1(d1, d2);
357         AliHLTTriggerDomain d4 = Expr::Apply2(d1, d2);
358         
359         for (int i = 1; i < N; i++)
360         for (int j = 1; j < N; j++)
361         for (int k = 1; k < N; k++)
362         {
363                 AliHLTDomainEntry entry(datatype[i], origin[j], spec[k]);
364                 bool d3Result = d3.Contains(entry);
365                 bool d4Result = d4.Contains(entry);
366                 if (d3Result != d4Result)
367                 {
368                         cout << "FAILED EquivalentExpressionsOK<" << Expr::Name() << "> test!" << endl;
369                         cout << "==============================================================================" << endl;
370                         cout << "Dump of the trigger domain a contents:" << endl;
371                         d1.Print();
372                         cout << "==============================================================================" << endl;
373                         cout << "Dump of the trigger domain b contents:" << endl;
374                         d2.Print();
375                         cout << "==============================================================================" << endl;
376                         cout << "Dump of the trigger domain c = " << Expr::Expr1() << " contents:" << endl;
377                         d3.Print();
378                         cout << "==============================================================================" << endl;
379                         cout << "Dump of the trigger domain d = " << Expr::Expr2() << " contents:" << endl;
380                         d3.Print();
381                         cout << "==============================================================================" << endl;
382                         cout << "Failed for entry = ";
383                         entry.Print();
384                         cout << "Result of c.Contains(entry) == " << d3Result << endl;
385                         cout << "Result of d.Contains(entry) == " << d4Result << endl;
386                         cout << "But the results should be the same." << endl;
387                         return false;
388                 }
389         }
390         
391         return true;
392 }
393
394
395 #define DefTest(name, routine, description) \
396         class name \
397         { \
398         public: \
399                 static bool Run(int opcount) \
400                 { \
401                         return routine(opcount); \
402                 } \
403                 static const char* Description() \
404                 { \
405                         return description; \
406                 } \
407         }
408
409 // Declarations of the different tests.
410 DefTest(AddRemoveTest,           AddRemoveOK,              "AliHLTTriggerDomain::Add and AliHLTTriggerDomain::Remove");
411 DefTest(ComplementOperationTest, OperatorOK<OpComplement>, "operator ~a");
412 DefTest(UnionOperationTest,      OperatorOK<OpUnion>,      "operator a | b");
413 DefTest(IntersectOperationTest,  OperatorOK<OpIntersect>,  "operator a & b");
414 DefTest(XorOperationTest,        OperatorOK<OpXor>,        "operator a ^ b");
415 DefTest(DifferenceOperationTest, OperatorOK<OpDifference>, "operator a - b");
416 DefTest(XorExpressionTest1,   EquivalentExpressionsOK<XorExprCheck1>,   "expression a ^ b == (a | b) - (a & b)");
417 DefTest(XorExpressionTest2,   EquivalentExpressionsOK<XorExprCheck2>,   "expression a ^ b == (a - (a & b)) | (b - (a & b))");
418 DefTest(MinusExpressionTest1, EquivalentExpressionsOK<MinusExprCheck1>, "expression a - b == a & (a ^ b)");
419 DefTest(MinusExpressionTest2, EquivalentExpressionsOK<MinusExprCheck2>, "expression a - b == a & ~(a & b)");
420
421 /**
422  * Routine to run an individual test.
423  * \param print  Should information be printed showing the progress of testing.
424  * \param numOfTests  The number of test iterations to run.
425  */
426 template <class Test>
427 bool Run(bool print = true, int numOfTests = 100)
428 {
429         if (print) cout << "Testing " << Test::Description() << " ..." << endl;
430         for (int i = 0; i < numOfTests; i++)
431         {
432                 if (not Test::Run(10)) return false;
433                 if (not Test::Run(100)) return false;
434                 if (not Test::Run(1000)) return false;
435                 if (print and ((i+1) % (numOfTests / 10) == 0))
436                 {
437                         cout << "  Completed " << ((i+1) * 100 / numOfTests) << "%" << endl;
438                 }
439         }
440         return true;
441 }
442
443 /**
444  * This is the top level testing method which calls individual tests.
445  * \param print  Should information be printed showing the progress of testing.
446  * \param numOfTests  The number of test iterations to run.
447  * \param seed  The random number seed to use.
448  */
449 bool testTriggerDomain(bool print = true, int numOfTests = 100, int seed = 0)
450 {
451         if (gClassTable->GetID("AliHLTDomainEntry") < 0)
452         {
453                 gSystem->Load("libAliHLTTrigger.so");
454         }
455         
456         gRandom->SetSeed(seed);
457         
458         if (not Run<AddRemoveTest>(print, numOfTests)) return false;
459         if (not Run<ComplementOperationTest>(print, numOfTests)) return false;
460         if (not Run<UnionOperationTest>(print, numOfTests)) return false;
461         if (not Run<IntersectOperationTest>(print, numOfTests)) return false;
462         if (not Run<XorOperationTest>(print, numOfTests)) return false;
463         if (not Run<DifferenceOperationTest>(print, numOfTests)) return false;
464         if (not Run<XorExpressionTest1>(print, numOfTests)) return false;
465         if (not Run<XorExpressionTest2>(print, numOfTests)) return false;
466         if (not Run<MinusExpressionTest1>(print, numOfTests)) return false;
467         if (not Run<MinusExpressionTest2>(print, numOfTests)) return false;
468         
469         return true;
470 }
471
472 #ifndef __MAKECINT__
473
474 int main(int /*argc*/, const char** /*argv*/)
475 {
476         bool resultOk = testTriggerDomain();
477         if (not resultOk) return 1;
478         return 0;
479 }
480
481 #endif // __MAKECINT__
482