1 /**************************************************************************
2 * This file is property of and copyright by the ALICE HLT Project *
3 * ALICE Experiment at CERN, All rights reserved. *
5 * Primary Authors: Artur Szostak <artursz@iafrica.com> *
6 * for The ALICE HLT Project. *
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 **************************************************************************/
18 * @file testMuonSpectroTrigger.C
19 * @author Artur Szostak <artursz@iafrica.com>
22 * This macro is used to test the AliHLTMuonSpectroTriggerComponent class.
23 * A basic test is run with the AliHLTSystem framework to check that the dHLT
24 * decision is interpreted correctly and the summary statistics generated properly.
27 #if defined(__CINT__) && (! defined(__MAKECINT__))
28 #error This macro must be compiled. Try running as testMuonSpectroTrigger.C++, but remember to load the libAliHLTTrigger.so and libAliHLTMUON.so libraries first.
31 #if !defined(__CINT__) || defined(__MAKECINT__)
33 #include "TClassTable.h"
36 #include "AliHLTReadoutList.h"
37 #include "AliHLTTriggerDomain.h"
38 #include "AliHLTTriggerDecision.h"
39 #include "AliHLTMuonSpectroScalars.h"
40 #include "AliHLTMUONDataBlockWriter.h"
41 #include "AliHLTMUONUtils.h"
42 #include "AliHLTSystem.h"
43 #include "AliHLTConfiguration.h"
44 #include "Riostream.h"
49 * Writes the indicated buffer to the given file name.
50 * \returns true if the file was written correctly and false otherwise.
52 bool WriteFile(const char* filename, void* buffer, unsigned int size)
54 FILE* file = fopen(filename, "w");
57 cerr << "ERROR: Could not create file: " << filename << endl;
60 fwrite(buffer, size, 1, file);
66 * Generates some sample input data and writes it into 6 files named
67 * testSinglesDecisionInputFile1.dat ... testSinglesDecisionInputFile3.dat and
68 * testPairsDecisionInputFile1.dat ... testPairsDecisionInputFile3.dat
70 void GenerateInputData()
72 if (gClassTable->GetID("AliHLTMuonSpectroTriggerComponent") < 0)
74 gSystem->Load("libAliHLTUtil.so");
75 gSystem->Load("libAliHLTTRD.so");
76 gSystem->Load("libAliHLTTrigger.so");
79 // Allocate two 1 MByte buffers, this will be more than enough space.
80 unsigned int bufferSize = 1024*1024;
81 void* buffer1 = new char[bufferSize];
82 void* buffer2 = new char[bufferSize];
84 AliHLTMUONSinglesDecisionBlockWriter singlesBlock(buffer1, bufferSize);
85 singlesBlock.InitCommonHeader();
86 AliHLTMUONSinglesDecisionBlockStruct& singlesHeader = singlesBlock.BlockHeader();
87 singlesHeader.fNlowPt = 2;
88 singlesHeader.fNhighPt = 1;
89 singlesBlock.SetNumberOfEntries(3);
90 AliHLTMUONTrackDecisionStruct& track1 = singlesBlock[0];
92 track1.fTriggerBits = AliHLTMUONUtils::PackTrackDecisionBits(false, false);
94 AliHLTMUONTrackDecisionStruct& track2 = singlesBlock[1];
96 track2.fTriggerBits = AliHLTMUONUtils::PackTrackDecisionBits(false, true);
98 AliHLTMUONTrackDecisionStruct& track3 = singlesBlock[2];
100 track3.fTriggerBits = AliHLTMUONUtils::PackTrackDecisionBits(true, true);
103 AliHLTMUONPairsDecisionBlockWriter pairsBlock(buffer2, bufferSize);
104 pairsBlock.InitCommonHeader();
105 AliHLTMUONPairsDecisionBlockStruct& pairsHeader = pairsBlock.BlockHeader();
106 pairsHeader.fNunlikeAnyPt = 1;
107 pairsHeader.fNunlikeLowPt = 1;
108 pairsHeader.fNunlikeHighPt = 1;
109 pairsHeader.fNlikeAnyPt = 2;
110 pairsHeader.fNlikeLowPt = 2;
111 pairsHeader.fNlikeHighPt = 1;
112 pairsHeader.fNmassAny = 1;
113 pairsHeader.fNmassLow = 1;
114 pairsHeader.fNmassHigh = 0;
115 pairsBlock.SetNumberOfEntries(3);
116 AliHLTMUONPairDecisionStruct& pair1 = pairsBlock[0];
119 pair1.fTriggerBits = AliHLTMUONUtils::PackPairDecisionBits(false, false, false, 0, 1);
120 pair1.fInvMass = 0.1;
121 AliHLTMUONPairDecisionStruct& pair2 = pairsBlock[1];
124 pair2.fTriggerBits = AliHLTMUONUtils::PackPairDecisionBits(false, true, true, 1, 1);
125 pair2.fInvMass = 3.1;
126 AliHLTMUONPairDecisionStruct& pair3 = pairsBlock[2];
129 pair3.fTriggerBits = AliHLTMUONUtils::PackPairDecisionBits(true, true, false, 1, 2);
130 pair3.fInvMass = 10.1;
132 if (! WriteFile("testSinglesDecisionInputFile1.dat", buffer1, singlesBlock.BytesUsed())) return;
133 if (! WriteFile("testPairsDecisionInputFile1.dat", buffer2, pairsBlock.BytesUsed())) return;
135 singlesHeader.fNlowPt = 2;
136 singlesHeader.fNhighPt = 1;
137 singlesBlock.SetNumberOfEntries(2);
139 track1.fTriggerBits = AliHLTMUONUtils::PackTrackDecisionBits(false, true);
142 track2.fTriggerBits = AliHLTMUONUtils::PackTrackDecisionBits(true, true);
145 pairsHeader.fNunlikeAnyPt = 1;
146 pairsHeader.fNunlikeLowPt = 1;
147 pairsHeader.fNunlikeHighPt = 1;
148 pairsHeader.fNlikeAnyPt = 0;
149 pairsHeader.fNlikeLowPt = 0;
150 pairsHeader.fNlikeHighPt = 0;
151 pairsHeader.fNmassAny = 1;
152 pairsHeader.fNmassLow = 1;
153 pairsHeader.fNmassHigh = 1;
154 pairsBlock.SetNumberOfEntries(1);
157 pair1.fTriggerBits = AliHLTMUONUtils::PackPairDecisionBits(true, true, true, 1, 2);
158 pair1.fInvMass = 9.7;
160 if (! WriteFile("testSinglesDecisionInputFile2.dat", buffer1, singlesBlock.BytesUsed())) return;
161 if (! WriteFile("testPairsDecisionInputFile2.dat", buffer2, pairsBlock.BytesUsed())) return;
163 singlesHeader.fNlowPt = 0;
164 singlesHeader.fNhighPt = 0;
165 singlesBlock.SetNumberOfEntries(1);
167 track1.fTriggerBits = AliHLTMUONUtils::PackTrackDecisionBits(false, false);
170 pairsHeader.fNunlikeAnyPt = 0;
171 pairsHeader.fNunlikeLowPt = 0;
172 pairsHeader.fNunlikeHighPt = 0;
173 pairsHeader.fNlikeAnyPt = 0;
174 pairsHeader.fNlikeLowPt = 0;
175 pairsHeader.fNlikeHighPt = 0;
176 pairsHeader.fNmassAny = 0;
177 pairsHeader.fNmassLow = 0;
178 pairsHeader.fNmassHigh = 0;
179 pairsBlock.SetNumberOfEntries(0);
181 if (! WriteFile("testSinglesDecisionInputFile3.dat", buffer1, singlesBlock.BytesUsed())) return;
182 if (! WriteFile("testPairsDecisionInputFile3.dat", buffer2, pairsBlock.BytesUsed())) return;
186 * Runs a small test chain for the muon spectrometer trigger component.
187 * \param debug If true then full logging is turned on.
188 * \param numOfEvents The number of events to run the chain for.
190 void RunTrigger(bool debug = false, int numOfEvents = 3)
193 sys.LoadComponentLibraries("libAliHLTUtil.so");
194 sys.LoadComponentLibraries("libAliHLTTRD.so");
195 sys.LoadComponentLibraries("libAliHLTMUON.so");
196 sys.LoadComponentLibraries("libAliHLTTrigger.so");
199 AliLog::SetGlobalLogLevel(AliLog::kMaxType);
200 sys.SetGlobalLoggingLevel(kHLTLogAll);
203 TString cmdline = "-datatype DECIDSIN MUON ";
204 for (int i = 1; i <= 3; i++)
206 if (i > 1) cmdline += " -nextevent";
207 cmdline += Form(" -datafile testSinglesDecisionInputFile%d.dat", i);
209 AliHLTConfiguration pub1("pub1", "FilePublisher", NULL, cmdline.Data());
211 cmdline = "-datatype DECIDPAR MUON ";
212 for (int i = 1; i <= 3; i++)
214 if (i > 1) cmdline += " -nextevent";
215 cmdline += Form(" -datafile testPairsDecisionInputFile%d.dat", i);
217 AliHLTConfiguration pub2("pub2", "FilePublisher", NULL, cmdline.Data());
219 AliHLTConfiguration proc("proc", "MuonSpectroTrigger", "pub1 pub2", "-makestats -triggerdimuons");
220 AliHLTConfiguration sink("sink", "ROOTFileWriter", "proc", "-datafile testMuonTriggerOutputFile.root -concatenate-events");
222 sys.BuildTaskList("sink");
223 sys.Run(numOfEvents);
228 * Checks that a particular decision and summary object are as expected and prints
229 * error messages if there are any problems with the results.
230 * \param eventNum The number of the event being checked.
231 * \param decision The trigger decision being checked.
232 * \param scalars The scalars object being checked.
233 * \param expectedResult The expected global trigger result.
234 * \param expectedDomain The expected resulting trigger domain.
235 * \param expectedDescription The expected resulting trigger description.
236 * \param expectedScalars The expected resulting scalars.
237 * \returns true if the decision and scalars are as expected.
241 AliHLTTriggerDecision* decision,
242 AliHLTMuonSpectroScalars* scalars,
244 AliHLTTriggerDomain expectedDomain,
245 TString expectedDescription,
246 AliHLTMuonSpectroScalars& expectedScalars
249 if (decision == NULL)
251 cerr << "ERROR: No decision found where expected for event "
252 << eventNum << "." << endl;
255 if (decision->Result() != expectedResult)
257 cerr << "ERROR: The result does not match the expected value for event "
258 << eventNum << ". Got " << decision->Result() << " but expected "
259 << expectedResult << "." << endl;
262 if (decision->TriggerDomain() != expectedDomain)
264 cerr << "ERROR: The domain does not match the expected value for event "
265 << eventNum << ". Got:" << endl;
266 decision->TriggerDomain().Print();
267 cerr << "but expected:" << endl;
268 expectedDomain.Print();
271 if (decision->Description() != expectedDescription)
273 cerr << "ERROR: The description does not match the expected value for event "
274 << eventNum << ". Got '" << decision->Description() << "' but expected '"
275 << expectedDescription << "'." << endl;
278 if (*scalars != expectedScalars)
280 cerr << "ERROR: The scalars summary object does not match the expected one for event "
281 << eventNum << ". Expected the following scalar values:" << endl;
282 expectedScalars.Print();
289 /// Routine for checking the results of the chain run in RunTrigger.
292 AliHLTTriggerDecision* decision = NULL;
293 AliHLTMuonSpectroScalars* scalars = NULL;
296 AliHLTTriggerDomain domainMUON("*******:MUON");
297 //domainMUON.Add(AliHLTReadoutList("MUONTRK"));
299 AliHLTMuonSpectroScalars emptyScalars;
301 AliHLTMuonSpectroScalars scalarsEvent1;
302 scalarsEvent1.Add("NTracks", "", 3);
303 scalarsEvent1.Add("NLowPt", "", 2);
304 scalarsEvent1.Add("NHighPt", "", 1);
305 scalarsEvent1.Add("MinPt", "", 0.9f);
306 scalarsEvent1.Add("MaxPt", "", 3.1f);
307 scalarsEvent1.Add("NLikeAny", "", 2);
308 scalarsEvent1.Add("NLikeLow", "", 2);
309 scalarsEvent1.Add("NLikeHigh", "", 1);
310 scalarsEvent1.Add("NUnlikeAny", "", 1);
311 scalarsEvent1.Add("NUnlikeLow", "", 1);
312 scalarsEvent1.Add("NUnlikeHigh", "", 1);
313 scalarsEvent1.Add("NLowMass", "", 1);
314 scalarsEvent1.Add("NHighMass", "", 0);
315 scalarsEvent1.Add("MinMass", "", 0.1f);
316 scalarsEvent1.Add("MaxMass", "", 10.1f);
318 AliHLTMuonSpectroScalars scalarsEvent2;
319 scalarsEvent2.Add("NTracks", "", 2);
320 scalarsEvent2.Add("NLowPt", "", 2);
321 scalarsEvent2.Add("NHighPt", "", 1);
322 scalarsEvent2.Add("MinPt", "", 1.2f);
323 scalarsEvent2.Add("MaxPt", "", 2.3f);
324 scalarsEvent2.Add("NLikeAny", "", 0);
325 scalarsEvent2.Add("NLikeLow", "", 0);
326 scalarsEvent2.Add("NLikeHigh", "", 0);
327 scalarsEvent2.Add("NUnlikeAny", "", 1);
328 scalarsEvent2.Add("NUnlikeLow", "", 1);
329 scalarsEvent2.Add("NUnlikeHigh", "", 1);
330 scalarsEvent2.Add("NLowMass", "", 1);
331 scalarsEvent2.Add("NHighMass", "", 1);
332 scalarsEvent2.Add("MinMass", "", 9.7f);
333 scalarsEvent2.Add("MaxMass", "", 9.7f);
335 AliHLTMuonSpectroScalars scalarsEvent3;
336 scalarsEvent3.Add("NTracks", "", 1);
337 scalarsEvent3.Add("NLowPt", "", 0);
338 scalarsEvent3.Add("NHighPt", "", 0);
339 scalarsEvent3.Add("MinPt", "", 0.6f);
340 scalarsEvent3.Add("MaxPt", "", 0.6f);
341 scalarsEvent3.Add("NLikeAny", "", 0);
342 scalarsEvent3.Add("NLikeLow", "", 0);
343 scalarsEvent3.Add("NLikeHigh", "", 0);
344 scalarsEvent3.Add("NUnlikeAny", "", 0);
345 scalarsEvent3.Add("NUnlikeLow", "", 0);
346 scalarsEvent3.Add("NUnlikeHigh", "", 0);
347 scalarsEvent3.Add("NLowMass", "", 0);
348 scalarsEvent3.Add("NHighMass", "", 0);
349 scalarsEvent3.Add("MinMass", "", -1);
350 scalarsEvent3.Add("MaxMass", "", -1);
352 TFile* file = new TFile("testMuonTriggerOutputFile.root", "READ");
354 // First event is the Start-Of-Run
355 decision = dynamic_cast<AliHLTTriggerDecision*>(file->Get("MuonSpectroTrigger;1"));
356 scalars = dynamic_cast<AliHLTMuonSpectroScalars*>(file->Get("AliHLTMuonSpectroScalars;1"));
357 result = Check(0, decision, scalars, false, AliHLTTriggerDomain(), "Not triggered", emptyScalars);
358 if (! result) goto cleanup;
359 // Now we have the 3 data events:
360 decision = dynamic_cast<AliHLTTriggerDecision*>(file->Get("MuonSpectroTrigger;2"));
361 scalars = dynamic_cast<AliHLTMuonSpectroScalars*>(file->Get("AliHLTMuonSpectroScalars;2"));
362 result = Check(1, decision, scalars, true, domainMUON, "Dimuon in muon spectrometer", scalarsEvent1);
363 if (! result) goto cleanup;
364 decision = dynamic_cast<AliHLTTriggerDecision*>(file->Get("MuonSpectroTrigger;3"));
365 scalars = dynamic_cast<AliHLTMuonSpectroScalars*>(file->Get("AliHLTMuonSpectroScalars;3"));
366 result = Check(2, decision, scalars, true, domainMUON, "Dimuon in muon spectrometer", scalarsEvent2);
367 if (! result) goto cleanup;
368 decision = dynamic_cast<AliHLTTriggerDecision*>(file->Get("MuonSpectroTrigger;4"));
369 scalars = dynamic_cast<AliHLTMuonSpectroScalars*>(file->Get("AliHLTMuonSpectroScalars;4"));
370 result = Check(3, decision, scalars, false, AliHLTTriggerDomain(), "Not triggered", scalarsEvent3);
371 if (! result) goto cleanup;
372 // and finally the End-Of-Run event.
373 decision = dynamic_cast<AliHLTTriggerDecision*>(file->Get("MuonSpectroTrigger;5"));
374 scalars = dynamic_cast<AliHLTMuonSpectroScalars*>(file->Get("AliHLTMuonSpectroScalars;5"));
375 result = Check(4, decision, scalars, false, AliHLTTriggerDomain(), "Not triggered", emptyScalars);
376 if (! result) goto cleanup;
382 if (decision != NULL)
384 cout << "========== Dumping received decision result ========== " << endl;
386 cout << "=========== Dumping received scalars result ========== " << endl;
395 * Runs the unit test for the AliHLTMuonSpectroTriggerComponent class.
396 * \param debug If specified then the HLT chain is run with full logging enabled.
397 * \returns true if the class passed the test and false otherwise.
399 bool testMuonSpectroTrigger(bool debug = false)
403 if (! CheckResults()) return false;
405 // Cleanup all temporary files generated.
406 gSystem->Exec("rm -f testMuonTriggerOutputFile.root test*DecisionInputFile*.dat");
413 int main(int /*argc*/, const char** /*argv*/)
415 bool resultOk = testMuonSpectroTrigger();
416 if (not resultOk) return 1;
420 #endif // __MAKECINT__