Major update required to handle old and new AliHLTEventDDL structures within HLT...
[u/mrichter/AliRoot.git] / HLT / BASE / test / testAliHLTReadoutList.C
CommitLineData
6506b8c2 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: Artur Szostak <artursz@iafrica.com> *
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 testAliHLTReadoutList.C
20/// @author Artur Szostak <artursz@iafrica.com>
21/// @date 8 June 2010
22/// @brief Test program for the AliHLTReadoutList class.
23///
24
25#if defined(__CINT__) && (! defined(__MAKECINT__))
26#error This macro must be compiled. Try running as testAliHLTReadoutList.C++.
27#endif
28
29#if !defined(__CINT__) || defined(__MAKECINT__)
30#include "AliHLTDataTypes.h"
31#include "AliHLTReadoutList.h"
32#include "AliHLTDAQ.h"
33#include "TRandom3.h"
34#include "TString.h"
35#include "Riostream.h"
36#include <vector>
37#include <algorithm>
38#endif
39
40// The detector codes as used by AliHLTReadoutList.
41const int kgNumberOfCodes = 21;
42const int kgDetCodes[kgNumberOfCodes] = {
43 AliHLTReadoutList::kITSSPD,
44 AliHLTReadoutList::kITSSDD,
45 AliHLTReadoutList::kITSSSD,
46 AliHLTReadoutList::kTPC,
47 AliHLTReadoutList::kTRD,
48 AliHLTReadoutList::kTOF,
49 AliHLTReadoutList::kHMPID,
50 AliHLTReadoutList::kPHOS,
51 AliHLTReadoutList::kCPV,
52 AliHLTReadoutList::kPMD,
53 AliHLTReadoutList::kMUONTRK,
54 AliHLTReadoutList::kMUONTRG,
55 AliHLTReadoutList::kFMD,
56 AliHLTReadoutList::kT0,
57 AliHLTReadoutList::kV0,
58 AliHLTReadoutList::kZDC,
59 AliHLTReadoutList::kACORDE,
60 AliHLTReadoutList::kTRG,
61 AliHLTReadoutList::kEMCAL,
62 AliHLTReadoutList::kDAQTEST,
63 AliHLTReadoutList::kHLT
64};
65const char* kgDetCodeName[kgNumberOfCodes] = {
66 "AliHLTReadoutList::kITSSPD",
67 "AliHLTReadoutList::kITSSDD",
68 "AliHLTReadoutList::kITSSSD",
69 "AliHLTReadoutList::kTPC",
70 "AliHLTReadoutList::kTRD",
71 "AliHLTReadoutList::kTOF",
72 "AliHLTReadoutList::kHMPID",
73 "AliHLTReadoutList::kPHOS",
74 "AliHLTReadoutList::kCPV",
75 "AliHLTReadoutList::kPMD",
76 "AliHLTReadoutList::kMUONTRK",
77 "AliHLTReadoutList::kMUONTRG",
78 "AliHLTReadoutList::kFMD",
79 "AliHLTReadoutList::kT0",
80 "AliHLTReadoutList::kV0",
81 "AliHLTReadoutList::kZDC",
82 "AliHLTReadoutList::kACORDE",
83 "AliHLTReadoutList::kTRG",
84 "AliHLTReadoutList::kEMCAL",
85 "AliHLTReadoutList::kDAQTEST",
86 "AliHLTReadoutList::kHLT"
87};
88
89/**
90 * Converts a code to string.
91 * \param code The ID code of the detector. One of AliHLTReadoutList::EDetectorId
92 * \returns the code name as a string given a the detector code.
93 */
94const char* CodeToString(int code)
95{
96 for (int i = 0; i < kgNumberOfCodes; ++i)
97 {
98 if (kgDetCodes[i] == code) return kgDetCodeName[i];
99 }
100 return "UNKNOWN";
101}
102
103/**
104 * Checks if the basic empty and clear methods work.
105 */
106bool CheckEmptyAndClear()
107{
108 AliHLTReadoutList rl;
109 if (rl.Empty() != true)
110 {
111 cerr << "ERROR: AliHLTReadoutList::Empty returns false for an empty readout list." << endl;
112 return false;
113 }
114
115 // Enable all the detectors and check this operation.
116 rl.Enable(AliHLTReadoutList::kALLDET);
117 for (int i = 0; i < kgNumberOfCodes; ++i)
118 {
119 if (i == 19) continue; // This is the test DDL. off by default.
120 if (not rl.DetectorEnabled(kgDetCodes[i]))
121 {
122 cerr << "ERROR: AliHLTReadoutList::Enable(AliHLTReadoutList::kALLDET) did not enable for "
123 << CodeToString(kgDetCodes[i]) << "." << endl;
124 return false;
125 }
126 }
127 if (rl.DetectorEnabled(AliHLTReadoutList::kDAQTEST))
128 {
129 cerr << "ERROR: AliHLTReadoutList::Enable(AliHLTReadoutList::kALLDET) enabled bits"
130 " for AliHLTReadoutList::kDAQTEST but should not have." << endl;
131 return false;
132 }
133
134 rl.Clear();
135 // Fetch the raw bits for the readout list structure and check that they
136 // are all zero, since we should have disabled everything in the loop above.
137 AliHLTEventDDL bits = rl;
138 if (bits.fCount != (unsigned int)gkAliHLTDDLListSize)
139 {
140 cerr << "ERROR: Typecast operator AliHLTEventDDL () is not"
141 " setting the fCount of the structure correctly." << endl;
142 return false;
143 }
144 for (int j = 0; j < gkAliHLTDDLListSize; ++j)
145 {
146 if (bits.fList[j] != 0x0)
147 {
148 cerr << "ERROR: Word " << j << " in internal AliHLTReadoutList"
149 " bitfield structure is not zero as expected after a"
150 " call to AliHLTReadoutList::Clear." << endl;
151 return false;
152 }
153 }
154
155 return true;
156}
157
158/**
159 * Tests enabling and disabling of different detectors.
160 */
161bool CheckEnablingDisabling()
162{
163 for (int i = 0; i < 10000; ++i)
164 {
165 // Get 3 random detector codes.
14da6b98 166 int detNum[3] = {
167 gRandom->Integer(kgNumberOfCodes),
168 gRandom->Integer(kgNumberOfCodes),
169 gRandom->Integer(kgNumberOfCodes)
170 };
6506b8c2 171 int code[3] = {
14da6b98 172 kgDetCodes[detNum[0]],
173 kgDetCodes[detNum[1]],
174 kgDetCodes[detNum[2]]
6506b8c2 175 };
176 // make sure the codes are not duplicated.
14da6b98 177 while (code[1] == code[0])
178 {
179 detNum[1] = gRandom->Integer(kgNumberOfCodes);
180 code[1] = kgDetCodes[detNum[1]];
181 }
182 while (code[2] == code[1] or code[2] == code[0])
183 {
184 detNum[2] = gRandom->Integer(kgNumberOfCodes);
185 code[2] = kgDetCodes[detNum[2]];
186 }
6506b8c2 187
188 // Choose the number of codes to use, from 1 to max 3.
189 int codeCount = gRandom->Integer(3) + 1;
190
191 // Build up the detector code list for the AliHLTReadoutList constructor.
192 int totalCode = 0;
193 for (int j = 0; j < codeCount; ++j) totalCode |= code[j];
194
195 AliHLTReadoutList rl(totalCode);
196 if (rl.Empty() == true)
197 {
198 cerr << "ERROR: AliHLTReadoutList::Empty returns true for a non empty readout list." << endl;
199 return false;
200 }
201
202 // Check that the correct detectors have been enabled and
203 // that we can disable a detector correctly.
204 for (int j = 0; j < codeCount; ++j)
205 {
206 if (rl.DetectorEnabled(code[j]) == false)
207 {
208 cerr << "ERROR: Detector was not enabled for "
209 << CodeToString(code[j]) << " by constructor." << endl;
210 return false;
211 }
89413559 212 if (rl.DetectorDisabled(code[j]) == true)
213 {
214 cerr << "ERROR: DetectorDisabled returned and incorrect result"
215 " when detectors enabled for "
216 << CodeToString(code[j]) << " by constructor." << endl;
217 return false;
218 }
14da6b98 219
220 // Also check each bit individualy according to AliHLTDAQ values.
221 int det = detNum[j];
222 int maxddls = AliHLTDAQ::NumberOfDdls(det);
223 for (int ddlindex = 0; ddlindex < maxddls; ++ddlindex)
224 {
225 int ddlid = AliHLTDAQ::DdlIDOffset(det) | (ddlindex & 0xFF);
226 if (rl.IsDDLDisabled(ddlid))
227 {
228 cerr << "ERROR: Bit not set for DDL " << ddlid
229 << ", even though detector "
230 << AliHLTDAQ::OnlineName(det)
231 << " was enabled." << endl;
232 return false;
233 }
234 }
235
6506b8c2 236 rl.Disable(code[j]);
237 if (rl.DetectorEnabled(code[j]) == true)
238 {
239 cerr << "ERROR: AliHLTReadoutList::Disable(x) is not working for x = "
240 << CodeToString(code[j]) << "." << endl;
241 return false;
242 }
89413559 243 if (rl.DetectorDisabled(code[j]) == false)
244 {
245 cerr << "ERROR: DetectorDisabled returned and incorrect result"
246 " when calling AliHLTReadoutList::Disable(x) for "
247 << CodeToString(code[j]) << "." << endl;
248 return false;
249 }
6506b8c2 250 }
251
252 // Fetch the raw bits for the readout list structure and check that they
253 // are all zero, since we should have disabled everything in the loop above.
254 AliHLTEventDDL bits = rl;
255 for (int j = 0; j < gkAliHLTDDLListSize; ++j)
256 {
257 if (bits.fList[j] != 0x0)
258 {
259 cerr << "ERROR: Word " << j << " in internal AliHLTReadoutList"
260 " bitfield structure is not zero as expected." << endl;
261 return false;
262 }
263 }
264 }
265 return true;
266}
267
268/**
269 * Tests enabling and disabling of different DDLs.
270 */
271bool CheckEnablingDisablingDDLs()
272{
273 for (int i = 0; i < 10000; ++i)
274 {
275 // Get random DDL IDs that are each unique.
276 std::vector<int> ddls;
277 int ddlCount = gRandom->Integer(100) + 1;
278 for (int j = 0; j < ddlCount; ++j)
279 {
280 int ddlid = -1;
281 do
282 {
283 int det = gRandom->Integer(AliHLTDAQ::NumberOfDetectors());
284 int maxddls = AliHLTDAQ::NumberOfDdls(det);
285 // The following is a special check since AliDAQ could be the newer version.
286 // det = 18 is for EMCAL and gkAliHLTDDLListSize = 30 indicates old version
287 // of AliHLTEventDDL before EMCAL expantion with DCAL.
288 if (det == 18 and gkAliHLTDDLListSize == 30 and maxddls > 24) maxddls = 24;
289 int ddlindex = gRandom->Integer(maxddls);
290 ddlid = AliHLTDAQ::DdlID(det, ddlindex);
291 if (std::find(ddls.begin(), ddls.end(), ddlid) != ddls.end()) ddlid = -1;
292 }
293 while (ddlid == -1);
294 ddls.push_back(ddlid);
295 }
296
297 // Build up the enable list for the AliHLTReadoutList constructor.
298 TString enableList;
299 for (size_t j = 0; j < ddls.size(); ++j)
300 {
301 char num[32];
302 sprintf(num, "%d", ddls[j]);
303 enableList += " ";
304 enableList += num;
305 }
306
307 AliHLTReadoutList rl(enableList.Data());
308 if (rl.Empty() == true)
309 {
310 cerr << "ERROR: AliHLTReadoutList::Empty returns true for a non empty readout list." << endl;
311 return false;
312 }
313
314 // Check that the correct DDLs have been enabled and
315 // that we can disable a DDL correctly.
316 for (size_t j = 0; j < ddls.size(); ++j)
317 {
318 if (rl.IsDDLEnabled(ddls[j]) == false)
319 {
320 cerr << "ERROR: DDL " << ddls[j] << " was not enabled by constructor." << endl;
321 return false;
322 }
323 rl.DisableDDLBit(ddls[j]);
324 if (rl.IsDDLDisabled(ddls[j]) == false)
325 {
326 cerr << "ERROR: AliHLTReadoutList::DisableDDLBit(x) is not working for x = "
327 << ddls[j] << "." << endl;
328 return false;
329 }
330 }
331
332 // Fetch the raw bits for the readout list structure and check that they
333 // are all zero, since we should have disabled everything in the loop above.
334 AliHLTEventDDL bits = rl;
335 for (int j = 0; j < gkAliHLTDDLListSize; ++j)
336 {
337 if (bits.fList[j] != 0x0)
338 {
339 cerr << "ERROR: Word " << j << " in internal AliHLTReadoutList"
340 " bitfield structure is not zero as expected." << endl;
341 return false;
342 }
343 }
344 }
345 return true;
346}
347
a9a3028c 348/**
349 * Tests if using incorrect DDL IDs returns zero or is ignored as expected.
350 */
351bool CheckIncorrectIDs()
352{
353 for (int i = 0; i < 1000000; ++i)
354 {
355 // Get random DDL ID outside the valid range.
356 int ddlid = -1;
357 int det = gRandom->Integer(AliHLTDAQ::NumberOfDetectors()+1);
358 if (det != AliHLTDAQ::NumberOfDetectors())
359 {
360 int maxddls = AliHLTDAQ::NumberOfDdls(det);
361 int ddlindex = gRandom->Integer(0xFF - maxddls) + maxddls;
362 ddlid = AliHLTDAQ::DdlIDOffset(det) | (ddlindex & 0xFF);
363 }
364 else
365 {
366 det = gRandom->Integer(11) + 20;
367 if (det == 30) det = 31;
368 int ddlindex = gRandom->Integer(0xFF);
369 ddlid = (det << 8) | (ddlindex & 0xFF);
370 }
371
372 AliHLTReadoutList rl;
373 if (rl.GetDDLBit(ddlid) != kFALSE)
374 {
375 cerr << "ERROR: Received a non zero result for invalid DDL " << ddlid << "." << endl;
376 return false;
377 }
378 AliHLTEventDDL before = rl;
379 rl.EnableDDLBit(ddlid);
380 AliHLTEventDDL after = rl;
381 if (memcmp(&before, &after, sizeof(AliHLTEventDDL)) != 0)
382 {
383 cerr << "ERROR: Modified AliHLTReadoutList structure using an invalid DDL "
384 << ddlid << "." << endl;
385 cerr << "========== Dump of bits before modification ==========" << endl;
386 for (unsigned int j = 0; j < before.fCount; ++j)
387 {
388 cerr << "[word " << dec << j << "] = " << hex << before.fList[j] << dec << endl;
389 }
390 cerr << "========== Dump of bits after modification ==========" << endl;
391 for (unsigned int j = 0; j < after.fCount; ++j)
392 {
393 cerr << "[word " << dec << j << "] = " << hex << after.fList[j] << dec << endl;
394 }
395 return false;
396 }
397 }
398 return true;
399}
400
89413559 401/**
402 * Tests if using incorrect DDL IDs returns zero or is ignored as expected.
403 */
404bool CheckWordIndexAndCount()
405{
406 int wordCovered[gkAliHLTDDLListSize];
407 for (int j = 0; j < gkAliHLTDDLListSize; ++j) wordCovered[j] = 0;
408
409 for (int i = 0; i < kgNumberOfCodes; ++i)
410 {
411 AliHLTReadoutList rl;
412 Int_t firstword = rl.GetFirstWord((AliHLTReadoutList::EDetectorId)kgDetCodes[i]);
413 if (firstword < 0 or gkAliHLTDDLListSize-1 < firstword)
414 {
415 cerr << "ERROR: AliHLTReadoutList::GetFirstWord(" << kgDetCodeName[i]
416 << ") returns " << firstword
417 << ", which is outside the valid range of [0.." << gkAliHLTDDLListSize-1
418 << "]." << endl;
419 return false;
420 }
421
422 Int_t lastword = firstword + rl.GetWordCount((AliHLTReadoutList::EDetectorId)kgDetCodes[i]);
423 if (lastword < 1 or gkAliHLTDDLListSize < lastword)
424 {
425 cerr << "ERROR: The sum AliHLTReadoutList::GetFirstWord(" << kgDetCodeName[i]
426 << ") + AliHLTReadoutList::GetWordCount(" << kgDetCodeName[i]
427 << ") gives " << lastword
428 << ", which is outside the valid range of [1.." << gkAliHLTDDLListSize
429 << "]." << endl;
430 return false;
431 }
432
433 for (int j = firstword; j < lastword; ++j)
434 {
435 if (wordCovered[j] == 1)
436 {
437 cerr << "ERROR: The combination of AliHLTReadoutList::GetWordCount(" << kgDetCodeName[i]
438 << ") and AliHLTReadoutList::GetWordCount(" << kgDetCodeName[i]
439 << ") overlaps with previous detectors. Check the mapping in these functions."
440 << endl;
441 return false;
442 }
443 wordCovered[j] = 1;
444 }
445
446 Int_t maxddls = AliHLTDAQ::NumberOfDdls(i);
447 Int_t ddlid = AliHLTDAQ::DdlIDOffset(i) | (gRandom->Integer(maxddls) & 0xFF);
448 rl.EnableDDLBit(ddlid);
449 if (rl.GetFirstUsedDetector() != kgDetCodes[i])
450 {
451 cerr << "ERROR: AliHLTReadoutList::GetFirstUsedDetector() did not return the correct value of"
452 << kgDetCodeName[i] << " after calling AliHLTReadoutList::EnableDDLBit("
453 << ddlid << ")." << endl;
454 return false;
455 }
456 if (rl.GetFirstUsedDetector((AliHLTReadoutList::EDetectorId)kgDetCodes[i]) != AliHLTReadoutList::kNoDetector)
457 {
458 cerr << "ERROR: AliHLTReadoutList::GetFirstUsedDetector(" << kgDetCodeName[i]
459 << "+1) did not return the correct value of AliHLTReadoutList::kNoDetector"
460 " after calling AliHLTReadoutList::EnableDDLBit("
461 << ddlid << ")." << endl;
462 return false;
463 }
464 }
465
466 for (int j = 0; j < gkAliHLTDDLListSize; ++j)
467 {
468 if (wordCovered[j] == 0)
469 {
470 cerr << "ERROR: The functions AliHLTReadoutList::GetWordCount"
471 " and AliHLTReadoutList::GetWordCount do not fully cover"
472 " all DDL readout list words." << endl;
473 return false;
474 }
475 }
476
477 return true;
478}
479
6506b8c2 480/**
481 * Runs the unit test for the AliHLTReadoutList class.
482 * \returns true if the class passed the test and false otherwise.
483 */
484bool testAliHLTReadoutList()
485{
486 gRandom->SetSeed(123);
487
488 if (AliHLTDAQ::NumberOfDetectors() != kgNumberOfCodes)
489 {
490 cerr << "ERROR: The testAliHLTReadoutList.C macro needs to be updated"
491 " or something went really wrong."
492 " The number of detectors reported by AliHLTDAQ is not "
493 << kgNumberOfCodes << ", as expected, but "
494 << AliHLTDAQ::NumberOfDetectors() << "." << endl;
495 return false;
496 }
497
498 if (not CheckEmptyAndClear()) return false;
499 if (not CheckEnablingDisabling()) return false;
500 if (not CheckEnablingDisablingDDLs()) return false;
a9a3028c 501 if (not CheckIncorrectIDs()) return false;
89413559 502 if (not CheckWordIndexAndCount()) return false;
6506b8c2 503
504 return true;
505}
506
507#ifndef __MAKECINT__
508
509int main(int /*argc*/, const char** /*argv*/)
510{
511 bool resultOk = testAliHLTReadoutList();
512 if (not resultOk) return 1;
513 return 0;
514}
515
516#endif // __MAKECINT__