3 /**************************************************************************
4 * This file is property of and copyright by the ALICE HLT Project *
5 * ALICE Experiment at CERN, All rights reserved. *
7 * Primary Authors: Artur Szostak <artursz@iafrica.com> *
8 * for The ALICE HLT Project. *
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 **************************************************************************/
19 /// @file testAliHLTReadoutList.C
20 /// @author Artur Szostak <artursz@iafrica.com>
22 /// @brief Test program for the AliHLTReadoutList class.
25 #if defined(__CINT__) && (! defined(__MAKECINT__))
26 #error This macro must be compiled. Try running as testAliHLTReadoutList.C++.
29 #if !defined(__CINT__) || defined(__MAKECINT__)
30 #include "AliHLTDataTypes.h"
31 #include "AliHLTReadoutList.h"
32 #include "AliHLTDAQ.h"
35 #include "Riostream.h"
40 // The detector codes as used by AliHLTReadoutList.
41 const int kgNumberOfCodes = 21;
42 const 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
65 const 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"
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.
94 const char* CodeToString(int code)
96 for (int i = 0; i < kgNumberOfCodes; ++i)
98 if (kgDetCodes[i] == code) return kgDetCodeName[i];
104 * Checks if the basic empty and clear methods work.
106 bool CheckEmptyAndClear()
108 AliHLTReadoutList rl;
109 if (rl.Empty() != true)
111 cerr << "ERROR: AliHLTReadoutList::Empty returns false for an empty readout list." << endl;
115 // Enable all the detectors and check this operation.
116 rl.Enable(AliHLTReadoutList::kALLDET);
117 for (int i = 0; i < kgNumberOfCodes; ++i)
119 if (i == 19) continue; // This is the test DDL. off by default.
120 if (not rl.DetectorEnabled(kgDetCodes[i]))
122 cerr << "ERROR: AliHLTReadoutList::Enable(AliHLTReadoutList::kALLDET) did not enable for "
123 << CodeToString(kgDetCodes[i]) << "." << endl;
127 if (rl.DetectorEnabled(AliHLTReadoutList::kDAQTEST))
129 cerr << "ERROR: AliHLTReadoutList::Enable(AliHLTReadoutList::kALLDET) enabled bits"
130 " for AliHLTReadoutList::kDAQTEST but should not have." << endl;
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)
140 cerr << "ERROR: Typecast operator AliHLTEventDDL () is not"
141 " setting the fCount of the structure correctly." << endl;
144 for (int j = 0; j < gkAliHLTDDLListSize; ++j)
146 if (bits.fList[j] != 0x0)
148 cerr << "ERROR: Word " << j << " in internal AliHLTReadoutList"
149 " bitfield structure is not zero as expected after a"
150 " call to AliHLTReadoutList::Clear." << endl;
159 * Tests enabling and disabling of different detectors.
161 bool CheckEnablingDisabling()
163 for (int i = 0; i < 10000; ++i)
165 // Get 3 random detector codes.
167 gRandom->Integer(kgNumberOfCodes),
168 gRandom->Integer(kgNumberOfCodes),
169 gRandom->Integer(kgNumberOfCodes)
172 kgDetCodes[detNum[0]],
173 kgDetCodes[detNum[1]],
174 kgDetCodes[detNum[2]]
176 // make sure the codes are not duplicated.
177 while (code[1] == code[0])
179 detNum[1] = gRandom->Integer(kgNumberOfCodes);
180 code[1] = kgDetCodes[detNum[1]];
182 while (code[2] == code[1] or code[2] == code[0])
184 detNum[2] = gRandom->Integer(kgNumberOfCodes);
185 code[2] = kgDetCodes[detNum[2]];
188 // Choose the number of codes to use, from 1 to max 3.
189 int codeCount = gRandom->Integer(3) + 1;
191 // Build up the detector code list for the AliHLTReadoutList constructor.
193 for (int j = 0; j < codeCount; ++j) totalCode |= code[j];
195 AliHLTReadoutList rl(totalCode);
196 if (rl.Empty() == true)
198 cerr << "ERROR: AliHLTReadoutList::Empty returns true for a non empty readout list." << endl;
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)
206 if (rl.DetectorEnabled(code[j]) == false)
208 cerr << "ERROR: Detector was not enabled for "
209 << CodeToString(code[j]) << " by constructor." << endl;
212 if (rl.DetectorDisabled(code[j]) == true)
214 cerr << "ERROR: DetectorDisabled returned and incorrect result"
215 " when detectors enabled for "
216 << CodeToString(code[j]) << " by constructor." << endl;
220 // Also check each bit individualy according to AliHLTDAQ values.
222 int maxddls = AliHLTDAQ::NumberOfDdls(det);
223 for (int ddlindex = 0; ddlindex < maxddls; ++ddlindex)
225 int ddlid = AliHLTDAQ::DdlIDOffset(det) | (ddlindex & 0xFF);
226 if (rl.IsDDLDisabled(ddlid))
228 cerr << "ERROR: Bit not set for DDL " << ddlid
229 << ", even though detector "
230 << AliHLTDAQ::OnlineName(det)
231 << " was enabled." << endl;
237 if (rl.DetectorEnabled(code[j]) == true)
239 cerr << "ERROR: AliHLTReadoutList::Disable(x) is not working for x = "
240 << CodeToString(code[j]) << "." << endl;
243 if (rl.DetectorDisabled(code[j]) == false)
245 cerr << "ERROR: DetectorDisabled returned and incorrect result"
246 " when calling AliHLTReadoutList::Disable(x) for "
247 << CodeToString(code[j]) << "." << endl;
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)
257 if (bits.fList[j] != 0x0)
259 cerr << "ERROR: Word " << j << " in internal AliHLTReadoutList"
260 " bitfield structure is not zero as expected." << endl;
269 * Tests enabling and disabling of different DDLs.
271 bool CheckEnablingDisablingDDLs()
273 for (int i = 0; i < 10000; ++i)
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)
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;
294 ddls.push_back(ddlid);
297 // Build up the enable list for the AliHLTReadoutList constructor.
299 for (size_t j = 0; j < ddls.size(); ++j)
302 sprintf(num, "%d", ddls[j]);
307 AliHLTReadoutList rl(enableList.Data());
308 if (rl.Empty() == true)
310 cerr << "ERROR: AliHLTReadoutList::Empty returns true for a non empty readout list." << endl;
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)
318 if (rl.IsDDLEnabled(ddls[j]) == false)
320 cerr << "ERROR: DDL " << ddls[j] << " was not enabled by constructor." << endl;
323 rl.DisableDDLBit(ddls[j]);
324 if (rl.IsDDLDisabled(ddls[j]) == false)
326 cerr << "ERROR: AliHLTReadoutList::DisableDDLBit(x) is not working for x = "
327 << ddls[j] << "." << endl;
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)
337 if (bits.fList[j] != 0x0)
339 cerr << "ERROR: Word " << j << " in internal AliHLTReadoutList"
340 " bitfield structure is not zero as expected." << endl;
349 * Tests if using incorrect DDL IDs returns zero or is ignored as expected.
351 bool CheckIncorrectIDs()
353 for (int i = 0; i < 1000000; ++i)
355 // Get random DDL ID outside the valid range.
357 int det = gRandom->Integer(AliHLTDAQ::NumberOfDetectors()+1);
358 if (det != AliHLTDAQ::NumberOfDetectors())
360 int maxddls = AliHLTDAQ::NumberOfDdls(det);
361 int ddlindex = gRandom->Integer(0xFF - maxddls) + maxddls;
362 ddlid = AliHLTDAQ::DdlIDOffset(det) | (ddlindex & 0xFF);
366 det = gRandom->Integer(11) + 20;
367 if (det == 30) det = 31;
368 int ddlindex = gRandom->Integer(0xFF);
369 ddlid = (det << 8) | (ddlindex & 0xFF);
372 AliHLTReadoutList rl;
373 if (rl.GetDDLBit(ddlid) != kFALSE)
375 cerr << "ERROR: Received a non zero result for invalid DDL " << ddlid << "." << endl;
378 AliHLTEventDDL before = rl;
379 rl.EnableDDLBit(ddlid);
380 AliHLTEventDDL after = rl;
381 if (memcmp(&before, &after, sizeof(AliHLTEventDDL)) != 0)
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)
388 cerr << "[word " << dec << j << "] = " << hex << before.fList[j] << dec << endl;
390 cerr << "========== Dump of bits after modification ==========" << endl;
391 for (unsigned int j = 0; j < after.fCount; ++j)
393 cerr << "[word " << dec << j << "] = " << hex << after.fList[j] << dec << endl;
402 * Tests the mapping of the AliHLTReadoutList::GetFirstWord, AliHLTReadoutList::GetWordCount
403 * and AliHLTReadoutList::GetDetectorFromWord methods.
405 bool CheckWordIndexAndCount()
407 int wordCovered[gkAliHLTDDLListSize];
408 for (int j = 0; j < gkAliHLTDDLListSize; ++j) wordCovered[j] = 0;
410 for (int i = 0; i < kgNumberOfCodes; ++i)
412 AliHLTReadoutList rl;
413 Int_t firstword = rl.GetFirstWord((AliHLTReadoutList::EDetectorId)kgDetCodes[i]);
414 if (firstword < 0 or gkAliHLTDDLListSize-1 < firstword)
416 cerr << "ERROR: AliHLTReadoutList::GetFirstWord(" << kgDetCodeName[i]
417 << ") returns " << firstword
418 << ", which is outside the valid range of [0.." << gkAliHLTDDLListSize-1
423 Int_t lastword = firstword + rl.GetWordCount((AliHLTReadoutList::EDetectorId)kgDetCodes[i]);
424 if (lastword < 1 or gkAliHLTDDLListSize < lastword)
426 cerr << "ERROR: The sum AliHLTReadoutList::GetFirstWord(" << kgDetCodeName[i]
427 << ") + AliHLTReadoutList::GetWordCount(" << kgDetCodeName[i]
428 << ") gives " << lastword
429 << ", which is outside the valid range of [1.." << gkAliHLTDDLListSize
434 for (int j = firstword; j < lastword; ++j)
436 if (wordCovered[j] == 1)
438 cerr << "ERROR: The combination of AliHLTReadoutList::GetWordCount(" << kgDetCodeName[i]
439 << ") and AliHLTReadoutList::GetWordCount(" << kgDetCodeName[i]
440 << ") overlaps with previous detectors. Check the mapping in these functions."
447 Int_t maxddls = AliHLTDAQ::NumberOfDdls(i);
448 Int_t ddlid = AliHLTDAQ::DdlIDOffset(i) | (gRandom->Integer(maxddls) & 0xFF);
449 rl.EnableDDLBit(ddlid);
450 if (rl.GetFirstUsedDetector() != kgDetCodes[i])
452 cerr << "ERROR: AliHLTReadoutList::GetFirstUsedDetector() did not return the correct value of"
453 << kgDetCodeName[i] << " after calling AliHLTReadoutList::EnableDDLBit("
454 << ddlid << ")." << endl;
457 if (rl.GetFirstUsedDetector((AliHLTReadoutList::EDetectorId)kgDetCodes[i]) != AliHLTReadoutList::kNoDetector)
459 cerr << "ERROR: AliHLTReadoutList::GetFirstUsedDetector(" << kgDetCodeName[i]
460 << "+1) did not return the correct value of AliHLTReadoutList::kNoDetector"
461 " after calling AliHLTReadoutList::EnableDDLBit("
462 << ddlid << ")." << endl;
467 for (int j = 0; j < gkAliHLTDDLListSize; ++j)
469 if (wordCovered[j] == 0)
471 cerr << "ERROR: The functions AliHLTReadoutList::GetWordCount"
472 " and AliHLTReadoutList::GetWordCount do not fully cover"
473 " all DDL readout list words." << endl;
478 // Check the mapping of GetDetectorFromWord
479 for (int j = 0; j < gkAliHLTDDLListSize; ++j)
481 AliHLTReadoutList::EDetectorId det = AliHLTReadoutList::GetDetectorFromWord(j);
482 Int_t firstword = AliHLTReadoutList::GetFirstWord(det);
483 Int_t lastword = firstword + AliHLTReadoutList::GetWordCount(det);
484 if (not (firstword <= j and j < lastword))
486 cerr << "ERROR: The function AliHLTReadoutList::GetDetectorFromWord returns "
487 << AliHLTReadoutList::DetectorIdToString(det)
489 << " but the GetFirstWord and GetWordCount methods indicate a different range."
490 << " The mapping is probably incorrect." << endl;
499 * Runs the unit test for the AliHLTReadoutList class.
500 * \returns true if the class passed the test and false otherwise.
502 bool testAliHLTReadoutList()
504 gRandom->SetSeed(123);
506 if (AliHLTDAQ::NumberOfDetectors() != kgNumberOfCodes)
508 cerr << "ERROR: The testAliHLTReadoutList.C macro needs to be updated"
509 " or something went really wrong."
510 " The number of detectors reported by AliHLTDAQ is not "
511 << kgNumberOfCodes << ", as expected, but "
512 << AliHLTDAQ::NumberOfDetectors() << "." << endl;
516 if (not CheckEmptyAndClear()) return false;
517 if (not CheckEnablingDisabling()) return false;
518 if (not CheckEnablingDisablingDDLs()) return false;
519 if (not CheckIncorrectIDs()) return false;
520 if (not CheckWordIndexAndCount()) return false;
527 int main(int /*argc*/, const char** /*argv*/)
529 bool resultOk = testAliHLTReadoutList();
530 if (not resultOk) return 1;
534 #endif // __MAKECINT__