]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/trigger/test/testGlobalTriggerComponent.C
Fixing problems with AliHLTGlobalTriggerComponent and failing test: testGlobalTrigger...
[u/mrichter/AliRoot.git] / HLT / trigger / test / testGlobalTriggerComponent.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   19 Dec 2008
21  *
22  * This macro is used to test the AliHLTGlobalTriggerComponent class.
23  * A number of tests are run with the AliHLTSystem framework to check that
24  * the automatically generated global trigger logic is generated correctly.
25  *
26  * This macro can also be used to debug the configuration that fails.
27  * If a configuration test fails then the global trigger logic implementation
28  * is left in a generated file with a name of the form \<AliHLTGlobalTriggerImpl_*.cxx\>.
29  * For example a file named like: AliHLTGlobalTriggerImpl_08869e64_c54b_11de_9717_0101007fbeef.cxx
30  * One can make manual modifications to this file and then rerun the test with
31  * these manual modifications with the following command in aliroot:
32  *  .x testGlobalTriggerComponent.C+(\<configVersion\>,"\<AliHLTGlobalTriggerImpl_*\>")
33  * where \<configVersion\> is the appropriate config version number as passed to the
34  * TriggerConfig.C file to initialise the configuration we want to test. Also take note
35  * that we only specify the root of the file name without the .cxx file name extention.
36  * For our example file name the command to execute in aliroot would be:
37  *  .x testGlobalTriggerComponent.C+(2,"AliHLTGlobalTriggerImpl_08869e64_c54b_11de_9717_0101007fbeef")
38  * where we are testing the 2nd trigger configuration in TriggerConfig.C.
39  */
40
41 #if defined(__CINT__) && (! defined(__MAKECINT__))
42 #error This macro must be compiled. Try running as testGlobalTriggerComponent.C++, but remember to load the libAliHLTTrigger.so library first.
43 #endif
44
45 #if !defined(__CINT__) || defined(__MAKECINT__)
46 #include "TSystem.h"
47 #include "TClassTable.h"
48 #include "TFile.h"
49 #include "AliLog.h"
50 #include "AliHLTReadoutList.h"
51 #include "AliHLTTriggerDomain.h"
52 #include "AliHLTTriggerDecision.h"
53 #include "AliHLTGlobalTriggerDecision.h"
54 #include "AliHLTEventSummary.h"
55 #include "AliHLTSystem.h"
56 #include "AliHLTConfiguration.h"
57 #include "Riostream.h"
58 #endif
59
60 /**
61  * Generates some sample input data and writes it into 8 files named
62  * testInputFile1.root ... testInputFile8.root
63  */
64 void GenerateInputData()
65 {
66         bool loadedLibs = false;
67         if (gClassTable->GetID("AliHLTGlobalTriggerComponent") < 0)
68         {
69                 gSystem->Load("libAliHLTUtil.so");
70                 gSystem->Load("libAliHLTTRD.so");
71                 gSystem->Load("libAliHLTMUON.so");
72                 gSystem->Load("libAliHLTTrigger.so");
73                 loadedLibs = true;
74         }
75
76         AliHLTReadoutList readoutList1("TPC");
77         AliHLTTriggerDomain triggerDomain1;
78         triggerDomain1.Add("CLUSTERS", "TPC ");
79         triggerDomain1.Add("TRACKS", "TPC ");
80         triggerDomain1.Add(readoutList1);
81         AliHLTTriggerDecision decision1(true, "triggerTPC", triggerDomain1, "TPC has data");
82         
83         AliHLTReadoutList readoutList2a("MUONTRK");
84         AliHLTReadoutList readoutList2b("MUONTRG");
85         AliHLTTriggerDomain triggerDomain2;
86         triggerDomain2.Add("TRACKS", "MUON");
87         triggerDomain2.Add(readoutList2a);
88         triggerDomain2.Add(readoutList2b);
89         AliHLTTriggerDecision decision2(true, "triggerMUON", triggerDomain2, "MUON has data");
90         
91         AliHLTReadoutList readoutList3("ITSSSD");
92         AliHLTTriggerDomain triggerDomain3;
93         triggerDomain3.Add("*******", "SSD ");
94         triggerDomain3.Add(readoutList3);
95         AliHLTTriggerDecision decision3(true, "triggerSSD", triggerDomain3, "SSD has data");
96         
97         AliHLTEventSummary summary1;
98         summary1.SetTriggerClass(0x1);
99         
100         AliHLTEventSummary summary2;
101         summary2.SetTriggerClass(0x2);
102         
103         TFile* file = new TFile("testInputFile1.root", "RECREATE");
104         decision1.Write("triggerTPC");
105         decision2.Write("triggerMUON");
106         decision3.Write("triggerSSD");
107         summary2.Write("summary");
108         delete file;
109         
110         file = new TFile("testInputFile2.root", "RECREATE");
111         decision1.Write("triggerTPC");
112         summary2.Write("summary");
113         delete file;
114         
115         file = new TFile("testInputFile3.root", "RECREATE");
116         decision2.Write("triggerMUON");
117         summary1.Write("summary");
118         delete file;
119         
120         file = new TFile("testInputFile4.root", "RECREATE");
121         decision3.Write("triggerSSD");
122         summary2.Write("summary");
123         delete file;
124         
125         file = new TFile("testInputFile5.root", "RECREATE");
126         decision1.Write("triggerTPC");
127         decision2.Write("triggerMUON");
128         summary1.Write("summary");
129         delete file;
130         
131         file = new TFile("testInputFile6.root", "RECREATE");
132         decision1.Write("triggerTPC");
133         decision3.Write("triggerSSD");
134         summary2.Write("summary");
135         delete file;
136         
137         file = new TFile("testInputFile7.root", "RECREATE");
138         decision2.Write("triggerMUON");
139         decision3.Write("triggerSSD");
140         summary1.Write("summary");
141         delete file;
142         
143         file = new TFile("testInputFile8.root", "RECREATE");
144         delete file;
145         
146         if (loadedLibs)
147         {
148                 gSystem->Unload("libAliHLTTrigger.so");
149                 gSystem->Unload("libAliHLTMUON.so");
150                 gSystem->Unload("libAliHLTTRD.so");
151                 gSystem->Unload("libAliHLTUtil.so");
152         }
153 }
154
155 /**
156  * Runs a small global trigger test chain with the different configuration as specified
157  * in TriggerConfig.C.
158  * \param config  The configuration version to pass to TriggerConfig.C
159  * \param usecint  If true then the global trigger component uses CINT to interpret
160  *     the code rather than compiling it.
161  * \param debug  If true then the global trigger component generates extra debug
162  *     statements in the on the fly AliHLTGlobalTriggerImp_*.cxx file.
163  * \param numOfEvents  The number of events to run the chain for.
164  * \param customClass  Names the custom class that should be loaded from the file
165  *     <i>\<customClass\>.cxx</i>. This is useful for debugging only. i.e. you can
166  *     edit a generated logic file and test it by hand.
167  */
168 void RunTrigger(int config = 0, bool usecint = false, bool debug = false, int numOfEvents = 8, const char* customClass = NULL)
169 {
170         AliHLTSystem sys;
171         sys.ScanOptions("ECS=CTP_TRIGGER_CLASS=00:TRIGGER-ALL:00-01-02-03-04-05-06-07-08-09-10-11-12-13-14-15-16-17");
172         sys.LoadComponentLibraries("libAliHLTUtil.so");
173         sys.LoadComponentLibraries("libAliHLTTRD.so");
174         sys.LoadComponentLibraries("libAliHLTMUON.so");
175         sys.LoadComponentLibraries("libAliHLTTrigger.so");
176         if (debug)
177         {
178                 AliLog::SetGlobalLogLevel(AliLog::kMaxType);
179                 sys.SetGlobalLoggingLevel(kHLTLogAll);
180         }
181         
182         TString cmdline = "-datatype ROOTTOBJ 'HLT ' ";
183         for (int i = 1; i <= 8; i++)
184         {
185                 if (i > 1) cmdline += " -nextevent";
186                 cmdline += Form(" -datafile testInputFile%d.root", i);
187         }
188         AliHLTConfiguration pub("pub", "ROOTFilePublisher", NULL, cmdline.Data());
189         
190         cmdline = Form("-config $ALICE_ROOT/HLT/trigger/test/TriggerConfig.C(%d)"
191                 " -includepath $ALICE_ROOT/include -includepath $ALICE_ROOT/HLT/BASE"
192                 " -includepath $ALICE_ROOT/HLT/trigger -include AliHLTEventSummary.h",
193                 config
194                 );
195         if (customClass != NULL) cmdline += Form(" -usecode %s.cxx %s", customClass, customClass);
196         if (usecint) cmdline += " -cint";
197         if (debug) cmdline += " -debug";
198         AliHLTConfiguration proc("proc", "HLTGlobalTrigger", "pub", cmdline.Data());
199         
200         AliHLTConfiguration sink("sink", "ROOTFileWriter", "proc", "-datafile testOutputFile.root -concatenate-events");
201         
202         sys.BuildTaskList("sink");
203         sys.Run(
204                 numOfEvents,
205                 1,  // Stop chain at end of run.
206                 0x1 // Active CTP trigger mask.
207         );
208 }
209
210 /**
211  * This method calls the RunTrigger method in an independant aliroot process.
212  * This is necessary since we get memory corruption if we run too many instances of
213  * AliHLTSystem in the same process.
214  */
215 void CallRunTrigger(
216                 int config = 0, bool usecint = false, bool debug = false,
217                 int numOfEvents = 8, const char* customClass = NULL,
218                 bool showOutput = false
219         )
220 {
221         const char* redirection = "> /dev/null";
222         const char* classNameString = "NULL";
223         if (showOutput) redirection = "";
224         if (customClass != NULL) classNameString = Form("\"%s\"", customClass);
225         const char* command = Form(
226                         "aliroot %s <<EOF\n"
227                         "gSystem->Load(\"libAliHLTUtil.so\");\n"
228                         "gSystem->Load(\"libAliHLTTRD.so\");\n"
229                         "gSystem->Load(\"libAliHLTMUON.so\");\n"
230                         "gSystem->Load(\"libAliHLTTrigger.so\");\n"
231                         "gSystem->SetIncludePath(\"-I${ALICE_ROOT}/include"
232                         " -I${ALICE_ROOT}/HLT/BASE -I${ALICE_ROOT}/HLT/trigger\");\n"
233                         ".L $ALICE_ROOT/HLT/trigger/test/testGlobalTriggerComponent.C+\n"
234                         "RunTrigger(%d,%d,%d,%d,%s);\n"
235                         "EOF\n",
236                         redirection,
237                         config,
238                         usecint,
239                         debug,
240                         numOfEvents,
241                         classNameString
242                 );
243         gSystem->Exec(command);
244 }
245
246 /**
247  * Checks that a particular decision is as expected and prints error messages
248  * if it is not.
249  * \param testName  The name of the test being run.
250  * \param eventNum  The number of the event being checked.
251  * \param decision  The global trigger decision being checked.
252  * \param expectedResult  The expected global trigger result.
253  * \param expectedDomain  The expected resulting global trigger domain.
254  * \param expectedDescription  The expected resulting trigger description.
255  * \returns true if the decision is as expected.
256  */
257 bool Check(
258                 const char* testName,
259                 int eventNum,
260                 AliHLTGlobalTriggerDecision* decision,
261                 bool expectedResult,
262                 AliHLTTriggerDomain expectedDomain,
263                 TString expectedDescription
264         )
265 {
266         if (decision == NULL)
267         {
268                 cerr << "ERROR (Test: " << testName
269                      << "): No decision found where expected for event "
270                      << eventNum << "." << endl;
271                 return false;
272         }
273         if (decision->Result() != expectedResult)
274         {
275                 cerr << "ERROR (Test: " << testName
276                      << "): The result does not match the expected value for event "
277                      << eventNum << ". Got " << decision->Result() << " but expected "
278                      << expectedResult << "." << endl;
279                 return false;
280         }
281         if (decision->TriggerDomain() != expectedDomain)
282         {
283                 cerr << "ERROR (Test: " << testName
284                      << "): The domain does not match the expected value for event "
285                      << eventNum << ". Got:" << endl;
286                 decision->TriggerDomain().Print();
287                 cerr << "but expected:" << endl;
288                 expectedDomain.Print();
289                 return false;
290         }
291         if (decision->Description() != expectedDescription)
292         {
293                 cerr << "ERROR (Test: " << testName
294                      << "): The description does not match the expected value for event "
295                      << eventNum << ". Got '" << decision->Description() << "' but expected '"
296                      << expectedDescription << "'." << endl;
297                 return false;
298         }
299         return true;
300 }
301
302
303 /// Routine for checking the result of the PriorityGroupTestConfig() config in TriggerConfig.C
304 bool CheckPriorityGroupTestConfig(const char* testName = "Priority group config")
305 {
306         AliHLTGlobalTriggerDecision* decision = NULL;
307         bool result = false;
308         
309         AliHLTTriggerDomain domainTPC("CLUSTERS:TPC ,TRACKS:TPC ");
310         domainTPC.Add(AliHLTReadoutList("TPC"));
311         AliHLTTriggerDomain domainMUON("TRACKS:MUON");
312         domainMUON.Add(AliHLTReadoutList("MUONTRK"));
313         domainMUON.Add(AliHLTReadoutList("MUONTRG"));
314         AliHLTTriggerDomain domainSSD("*******:SSD ");
315         domainSSD.Add(AliHLTReadoutList("ITSSSD"));
316
317         TFile* file = new TFile("testOutputFile.root", "READ");
318         
319         // Triggers in events (i.e. input triggers):
320         // event 1: TPC MUON SSD
321         // event 2: TPC
322         // event 3: MUON
323         // event 4: SSD
324         // event 5: TPC MUON
325         // event 6: TPC SSD
326         // event 7: MUON SSD
327         // event 8: (empty)
328         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;1"));
329         result = Check(testName, 1, decision, true, domainSSD, "Fast SSD trigger");
330         if (! result) goto cleanup;
331         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;2"));
332         result = Check(testName, 2, decision, true, domainTPC, "TPC trigger");
333         if (! result) goto cleanup;
334         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;3"));
335         result = Check(testName, 3, decision, true, domainMUON, "MUON trigger");
336         if (! result) goto cleanup;
337         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;4"));
338         result = Check(testName, 4, decision, true, domainSSD, "MUON trigger");
339         if (! result) goto cleanup;
340         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;5"));
341         result = Check(testName, 5, decision, true, domainMUON, "MUON trigger");
342         if (! result) goto cleanup;
343         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;6"));
344         result = Check(testName, 6, decision, true, domainSSD, "Fast SSD trigger");
345         if (! result) goto cleanup;
346         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;7"));
347         result = Check(testName, 7, decision, true, domainMUON | domainSSD, "MUON trigger");
348         if (! result) goto cleanup;
349         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;8"));
350         result = Check(testName, 8, decision, false, AliHLTTriggerDomain(), "No trigger");
351         if (! result) goto cleanup;
352         
353         delete file;
354         return true;
355         
356 cleanup:
357         if (decision != NULL)
358         {
359                 cout << "========== Dumping incorrect decision ========== " << endl;
360                 decision->Print();
361         }
362         delete file;
363         return false;
364 }
365
366
367 /// Routine for checking the result of the SingleGroupTestConfig() config in TriggerConfig.C
368 bool CheckSingleGroupTestConfig(const char* testName = "Single group config")
369 {
370         AliHLTGlobalTriggerDecision* decision = NULL;
371         bool result = false;
372         
373         AliHLTTriggerDomain domainTPC("CLUSTERS:TPC ,TRACKS:TPC ");
374         domainTPC.Add(AliHLTReadoutList("TPC"));
375         AliHLTTriggerDomain domainMUON("TRACKS:MUON");
376         domainMUON.Add(AliHLTReadoutList("MUONTRK"));
377         domainMUON.Add(AliHLTReadoutList("MUONTRG"));
378         AliHLTTriggerDomain domainSSD("*******:SSD ");
379         domainSSD.Add(AliHLTReadoutList("ITSSSD"));
380
381         TFile* file = new TFile("testOutputFile.root", "READ");
382         
383         // Triggers in events (i.e. input triggers):
384         // event 1: TPC MUON SSD
385         // event 2: TPC
386         // event 3: MUON
387         // event 4: SSD
388         // event 5: TPC MUON
389         // event 6: TPC SSD
390         // event 7: MUON SSD
391         // event 8: (empty)
392         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;1"));
393         result = Check(testName, 1, decision, true, domainTPC | domainMUON | domainSSD, "TPC trigger,MUON trigger,SSD trigger");
394         if (! result) goto cleanup;
395         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;2"));
396         result = Check(testName, 2, decision, true, domainTPC, "TPC trigger");
397         if (! result) goto cleanup;
398         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;3"));
399         result = Check(testName, 3, decision, true, domainMUON, "MUON trigger");
400         if (! result) goto cleanup;
401         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;4"));
402         result = Check(testName, 4, decision, true, domainSSD, "SSD trigger");
403         if (! result) goto cleanup;
404         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;5"));
405         result = Check(testName, 5, decision, true, domainTPC | domainMUON, "TPC trigger,MUON trigger");
406         if (! result) goto cleanup;
407         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;6"));
408         result = Check(testName, 6, decision, true, domainTPC | domainSSD, "TPC trigger,SSD trigger");
409         if (! result) goto cleanup;
410         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;7"));
411         result = Check(testName, 7, decision, true, domainMUON | domainSSD, "MUON trigger,SSD trigger");
412         if (! result) goto cleanup;
413         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;8"));
414         result = Check(testName, 8, decision, false, AliHLTTriggerDomain(), "");
415         if (! result) goto cleanup;
416         
417         delete file;
418         return true;
419         
420 cleanup:
421         if (decision != NULL)
422         {
423                 cout << "========== Dumping incorrect decision ========== " << endl;
424                 decision->Print();
425         }
426         delete file;
427         return false;
428 }
429
430
431 /// Routine for checking the result of the PrescalarTestConfig() config in TriggerConfig.C
432 bool CheckPrescalarTestConfig(const char* testName = "Prescalar config")
433 {
434         AliHLTGlobalTriggerDecision* decision = NULL;
435         bool result = false;
436         
437         AliHLTTriggerDomain domainTPC("CLUSTERS:TPC ,TRACKS:TPC ");
438         domainTPC.Add(AliHLTReadoutList("TPC"));
439         AliHLTTriggerDomain domainMUON("TRACKS:MUON");
440         domainMUON.Add(AliHLTReadoutList("MUONTRK"));
441         domainMUON.Add(AliHLTReadoutList("MUONTRG"));
442         AliHLTTriggerDomain domainSSD("*******:SSD ");
443         domainSSD.Add(AliHLTReadoutList("ITSSSD"));
444         AliHLTTriggerDomain defaultDomain("*******:HLT ");
445
446         TFile* file = new TFile("testOutputFile.root", "READ");
447         
448         // Triggers in events (i.e. input triggers):
449         // event 1: TPC MUON SSD
450         // event 2: TPC
451         // event 3: MUON
452         // event 4: SSD
453         // event 5: TPC MUON
454         // event 6: TPC SSD
455         // event 7: MUON SSD
456         // event 8: (empty)
457         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;1"));
458         result = Check(testName, 1, decision, true, domainTPC, "TPC trigger");
459         if (! result) goto cleanup;
460         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;2"));
461         result = Check(testName, 2, decision, false, defaultDomain, "No trigger");
462         if (! result) goto cleanup;
463         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;3"));
464         result = Check(testName, 3, decision, true, domainMUON, "MUON trigger");
465         if (! result) goto cleanup;
466         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;4"));
467         result = Check(testName, 4, decision, false, defaultDomain, "No trigger");
468         if (! result) goto cleanup;
469         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;5"));
470         result = Check(testName, 5, decision, true, domainMUON, "MUON trigger");
471         if (! result) goto cleanup;
472         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;6"));
473         result = Check(testName, 6, decision, true, domainTPC, "TPC trigger");
474         if (! result) goto cleanup;
475         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;7"));
476         result = Check(testName, 7, decision, true, domainMUON, "MUON trigger");
477         if (! result) goto cleanup;
478         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;8"));
479         result = Check(testName, 8, decision, false, defaultDomain, "No trigger");
480         if (! result) goto cleanup;
481         
482         delete file;
483         return true;
484         
485 cleanup:
486         if (decision != NULL)
487         {
488                 cout << "========== Dumping incorrect decision ========== " << endl;
489                 decision->Print();
490         }
491         delete file;
492         return false;
493 }
494
495
496 /// Routine for checking the result of the SymbolTestConfig() config in TriggerConfig.C
497 bool CheckSymbolTestConfig(const char* testName = "Symbol config")
498 {
499         AliHLTGlobalTriggerDecision* decision = NULL;
500         bool result = false;
501         
502         AliHLTTriggerDomain domainAll("*******:***,-DAQRDOUT:TST");
503         AliHLTTriggerDomain domainPHOS("CLUSTERS:PHOS,TRACKS:PHOS");
504         AliHLTTriggerDomain domainTPC("CLUSTERS:TPC ,TRACKS:TPC ");
505         domainTPC.Add(AliHLTReadoutList("TPC"));
506         AliHLTTriggerDomain domainMUON("TRACKS:MUON");
507         domainMUON.Add(AliHLTReadoutList("MUONTRK"));
508         domainMUON.Add(AliHLTReadoutList("MUONTRG"));
509         AliHLTTriggerDomain domainSSD("*******:SSD ");
510         domainSSD.Add(AliHLTReadoutList("ITSSSD"));
511
512         TFile* file = new TFile("testOutputFile.root", "READ");
513         
514         // Triggers in events (i.e. input triggers) and trigger classes in AliHLTEventSummary:
515         // event 1: TPC MUON SSD, 0x2
516         // event 2: TPC         , 0x2
517         // event 3: MUON        , 0x1
518         // event 4: SSD         , 0x2
519         // event 5: TPC MUON    , 0x1
520         // event 6: TPC SSD     , 0x2
521         // event 7: MUON SSD    , 0x1
522         // event 8: (empty)     , 0x0
523         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;1"));
524         result = Check(testName, 1, decision, true, domainAll - AliHLTTriggerDomain("DAQRDOUT:EMC"), "Pass through");
525         if (! result) goto cleanup;
526         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;2"));
527         result = Check(testName, 2, decision, true, domainTPC | domainPHOS, "Trigger class 2");
528         if (! result) goto cleanup;
529         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;3"));
530         result = Check(testName, 3, decision, false, AliHLTTriggerDomain(), "");
531         if (! result) goto cleanup;
532         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;4"));
533         result = Check(testName, 4, decision, true, domainPHOS, "Trigger class 2");
534         if (! result) goto cleanup;
535         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;5"));
536         result = Check(testName, 5, decision, true, domainAll - AliHLTTriggerDomain("DAQRDOUT:EMC"), "Pass through");
537         if (! result) goto cleanup;
538         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;6"));
539         result = Check(testName, 6, decision, true, domainTPC | domainPHOS, "Trigger class 2");
540         if (! result) goto cleanup;
541         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;7"));
542         result = Check(testName, 7, decision, false, AliHLTTriggerDomain(), "");
543         if (! result) goto cleanup;
544         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;8"));
545         result = Check(testName, 8, decision, false, AliHLTTriggerDomain(), "");
546         if (! result) goto cleanup;
547         
548         delete file;
549         return true;
550         
551 cleanup:
552         if (decision != NULL)
553         {
554                 cout << "========== Dumping incorrect decision ========== " << endl;
555                 decision->Print();
556         }
557         delete file;
558         return false;
559 }
560
561
562 /// Routine for checking the result of the ComplexTestConfig() config in TriggerConfig.C
563 bool CheckComplexTestConfig(const char* testName = "Complex config")
564 {
565         AliHLTGlobalTriggerDecision* decision = NULL;
566         bool result = false;
567         
568         AliHLTTriggerDomain domainAll("*******:***,-DAQRDOUT:TST,-DAQRDOUT:EMC");
569         AliHLTTriggerDomain domainPHOS("CLUSTERS:PHOS,TRACKS:PHOS");
570         AliHLTTriggerDomain domainTPC("CLUSTERS:TPC ,TRACKS:TPC ");
571         domainTPC.Add(AliHLTReadoutList("TPC"));
572         AliHLTTriggerDomain domainMUON("TRACKS:MUON");
573         domainMUON.Add(AliHLTReadoutList("MUONTRK"));
574         domainMUON.Add(AliHLTReadoutList("MUONTRG"));
575         AliHLTTriggerDomain domainSSD("*******:SSD ");
576         domainSSD.Add(AliHLTReadoutList("ITSSSD"));
577
578         TFile* file = new TFile("testOutputFile.root", "READ");
579         
580         // Triggers in events (i.e. input triggers) and trigger classes in AliHLTEventSummary:
581         // event 1: TPC MUON SSD, 0x2
582         // event 2: TPC         , 0x2
583         // event 3: MUON        , 0x1
584         // event 4: SSD         , 0x2
585         // event 5: TPC MUON    , 0x1
586         // event 6: TPC SSD     , 0x2
587         // event 7: MUON SSD    , 0x1
588         // event 8: (empty)     , 0x0
589         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;1"));
590         result = Check(testName, 1, decision, true, domainAll, "Pass through");
591         if (! result) goto cleanup;
592         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;2"));
593         result = Check(testName, 2, decision, true, domainTPC, "Slow trigger");
594         if (! result) goto cleanup;
595         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;3"));
596         result = Check(testName, 3, decision, true, domainMUON, "MUON trigger 2");
597         if (! result) goto cleanup;
598         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;4"));
599         result = Check(testName, 4, decision, true, domainSSD | domainPHOS, "SSD trigger 2");
600         if (! result) goto cleanup;
601         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;5"));
602         result = Check(testName, 5, decision, true, domainMUON, "MUON trigger 2");
603         if (! result) goto cleanup;
604         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;6"));
605         result = Check(testName, 6, decision, true, domainSSD | domainPHOS, "SSD trigger 2");
606         if (! result) goto cleanup;
607         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;7"));
608         result = Check(testName, 7, decision, true, domainSSD | domainMUON, "SSD trigger 1,MUON trigger 1");
609         if (! result) goto cleanup;
610         decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;8"));
611         result = Check(testName, 8, decision, true, domainAll, "Pass through");
612         if (! result) goto cleanup;
613         
614         delete file;
615         return true;
616         
617 cleanup:
618         if (decision != NULL)
619         {
620                 cout << "========== Dumping incorrect decision ========== " << endl;
621                 decision->Print();
622         }
623         delete file;
624         return false;
625 }
626
627
628 typedef bool (*CheckFunctionType)(const char* testName);
629
630 /**
631  * This will check the results of a global trigger run with a particular checking
632  * routine and for different combinations of -cint and -debug flags passed to the
633  * global trigger component.
634  * It is important to check these flag combinations to make sure that everything
635  * is functioning the same under all the different combinations as it should.
636  * \param function  The checking routine to use.
637  * \param version  The trigger menu configuration version to use in <i>RunTrigger</i>.
638  * \param testName  The name of the test being run.
639  * \param numOfEvents  The number of events to run the chain for.
640  * \param customClass  Name of the custom class as passed to <i>RunTrigger</i>.
641  * \param showOutput  If true then the output from the RunTrigger method is not suppressed.
642  * \returns true if the different checks succeeded and false otherwise.
643  */
644 bool CheckDifferentModes(
645                 CheckFunctionType function, int version, const char* testName,
646                 int numOfEvents = 8, const char* customClass = NULL,
647                 bool showOutput = false
648         )
649 {
650         TString name = testName;
651         name += " in debug mode";
652         cout << "#################### Running test: " << name.Data() << " ####################" << endl;
653         CallRunTrigger(version, false, true, numOfEvents, customClass, showOutput);
654         if (! function(testName)) return false;
655         gSystem->Exec("rm -f testOutputFile.root");  // Cleanup output file for next test.
656         
657         name = testName;
658         cout << "#################### Running test: " << name.Data() << " ####################" << endl;
659         CallRunTrigger(version, false, false, numOfEvents, customClass, showOutput);
660         if (! function(testName)) return false;
661         gSystem->Exec("rm -f testOutputFile.root");  // Cleanup output file for next test.
662         
663         name = testName;
664         name += " interpreted with CINT in debug mode";
665         cout << "#################### Running test: " << name.Data() << " ####################" << endl;
666         CallRunTrigger(version, true, true, numOfEvents, customClass, showOutput);
667         if (! function(testName)) return false;
668         gSystem->Exec("rm -f testOutputFile.root");  // Cleanup output file for next test.
669         
670         name = testName;
671         name += " interpreted with CINT";
672         cout << "#################### Running test: " << name.Data() << " ####################" << endl;
673         CallRunTrigger(version, true, false, numOfEvents, customClass, showOutput);
674         if (! function(testName)) return false;
675         gSystem->Exec("rm -f testOutputFile.root");  // Cleanup output file for next test.
676         
677         return true;
678 }
679
680 /**
681  * Runs several tests for the AliHLTGlobalTriggerComponent class.
682  * We specifically test if the global trigger menu configuration is interpreted
683  * correctly and the trigger logic generated correctly on the fly.
684  * \param configVersion  The appropriate version number of the config being tested
685  *     which is passed to TriggerConfig.C.
686  * \param customClass  Name of the custom class as passed to <i>CheckDifferentModes</i>.
687  * \returns true if the different checks succeeded and false otherwise.
688  * \param numOfEvents  The number of events to run the chain for.
689  * \returns true if all the tests succeeded and false otherwise.
690  */
691 bool testGlobalTriggerComponent(int configVersion = -1, const char* customClass = NULL, int numOfEvents = 8)
692 {
693         GenerateInputData();
694         
695         if (configVersion != -1)
696         {
697                 CheckFunctionType function = NULL;
698                 switch (configVersion)
699                 {
700                 case 0: function = CheckPriorityGroupTestConfig; break;
701                 case 1: function = CheckSingleGroupTestConfig; break;
702                 case 2: function = CheckPrescalarTestConfig; break;
703                 case 3: function = CheckSymbolTestConfig; break;
704                 case 4: function = CheckComplexTestConfig; break;
705                 default:
706                         cerr << "ERROR: Invalid value for configVersion specified." << endl;
707                         return false;
708                 }
709                 bool result = CheckDifferentModes(
710                                 function,
711                                 configVersion,
712                                 Form("Config version %d", configVersion),
713                                 numOfEvents,
714                                 customClass,
715                                 true
716                         );
717                 return result;
718         }
719         
720         if (! CheckDifferentModes(CheckPriorityGroupTestConfig, 0, "Priority group config", numOfEvents, customClass)) return false;
721         if (! CheckDifferentModes(CheckSingleGroupTestConfig, 1, "Single group config", numOfEvents, customClass)) return false;
722         if (! CheckDifferentModes(CheckPrescalarTestConfig, 2, "Prescalar config", numOfEvents, customClass)) return false;
723         if (! CheckDifferentModes(CheckSymbolTestConfig, 3, "Symbol config", numOfEvents, customClass)) return false;
724         if (! CheckDifferentModes(CheckComplexTestConfig, 4, "Complex config", numOfEvents, customClass)) return false;
725         
726         // Cleanup all temporary files generated.
727         gSystem->Exec("rm -f testOutputFile.root testInputFile*.root AliHLTGlobalTriggerImpl*");
728         return true;
729 }
730
731
732 #ifndef __MAKECINT__
733
734 int main(int /*argc*/, const char** /*argv*/)
735 {
736         bool resultOk = testGlobalTriggerComponent();
737         if (not resultOk) return 1;
738         return 0;
739 }
740
741 #endif // __MAKECINT__