fbc639f087a6890797429089af509c5d67fe8af1
[u/mrichter/AliRoot.git] / HLT / BASE / test / testAliHLTReadoutList.C
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.
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
64 };
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"
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  */
94 const 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  */
106 bool 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  */
161 bool CheckEnablingDisabling()
162 {
163         for (int i = 0; i < 10000; ++i)
164         {
165                 // Get 3 random detector codes.
166                 int detNum[3] = {
167                         gRandom->Integer(kgNumberOfCodes),
168                         gRandom->Integer(kgNumberOfCodes),
169                         gRandom->Integer(kgNumberOfCodes)
170                 };
171                 int code[3] = {
172                         kgDetCodes[detNum[0]],
173                         kgDetCodes[detNum[1]],
174                         kgDetCodes[detNum[2]]
175                 };
176                 // make sure the codes are not duplicated.
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                 }
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                         }
212                         
213                         // Also check each bit individualy according to AliHLTDAQ values.
214                         int det = detNum[j];
215                         int maxddls = AliHLTDAQ::NumberOfDdls(det);
216                         for (int ddlindex = 0; ddlindex < maxddls; ++ddlindex)
217                         {
218                                 int ddlid = AliHLTDAQ::DdlIDOffset(det) | (ddlindex & 0xFF);
219                                 if (rl.IsDDLDisabled(ddlid))
220                                 {
221                                         cerr << "ERROR: Bit not set for DDL " << ddlid
222                                                 << ", even though detector "
223                                                 << AliHLTDAQ::OnlineName(det)
224                                                 << " was enabled." << endl;
225                                         return false;
226                                 }
227                         }
228                         
229                         rl.Disable(code[j]);
230                         if (rl.DetectorEnabled(code[j]) == true)
231                         {
232                                 cerr << "ERROR: AliHLTReadoutList::Disable(x) is not working for x = "
233                                         << CodeToString(code[j]) << "." << endl;
234                                 return false;
235                         }
236                 }
237                 
238                 // Fetch the raw bits for the readout list structure and check that they
239                 // are all zero, since we should have disabled everything in the loop above.
240                 AliHLTEventDDL bits = rl;
241                 for (int j = 0; j < gkAliHLTDDLListSize; ++j)
242                 {
243                         if (bits.fList[j] != 0x0)
244                         {
245                                 cerr << "ERROR: Word " << j << " in internal AliHLTReadoutList"
246                                         " bitfield structure is not zero as expected." << endl;
247                                 return false;
248                         }
249                 }
250         }
251         return true;
252 }
253
254 /**
255  * Tests enabling and disabling of different DDLs.
256  */
257 bool CheckEnablingDisablingDDLs()
258 {
259         for (int i = 0; i < 10000; ++i)
260         {
261                 // Get random DDL IDs that are each unique.
262                 std::vector<int> ddls;
263                 int ddlCount = gRandom->Integer(100) + 1;
264                 for (int j = 0; j < ddlCount; ++j)
265                 {
266                         int ddlid = -1;
267                         do
268                         {
269                                 int det = gRandom->Integer(AliHLTDAQ::NumberOfDetectors());
270                                 int maxddls = AliHLTDAQ::NumberOfDdls(det);
271                                 // The following is a special check since AliDAQ could be the newer version.
272                                 // det = 18 is for EMCAL and gkAliHLTDDLListSize = 30 indicates old version
273                                 // of AliHLTEventDDL before EMCAL expantion with DCAL.
274                                 if (det == 18 and gkAliHLTDDLListSize == 30 and maxddls > 24) maxddls = 24;
275                                 int ddlindex = gRandom->Integer(maxddls);
276                                 ddlid = AliHLTDAQ::DdlID(det, ddlindex);
277                                 if (std::find(ddls.begin(), ddls.end(), ddlid) != ddls.end()) ddlid = -1;
278                         }
279                         while (ddlid == -1);
280                         ddls.push_back(ddlid);
281                 }
282                 
283                 // Build up the enable list for the AliHLTReadoutList constructor.
284                 TString enableList;
285                 for (size_t j = 0; j < ddls.size(); ++j)
286                 {
287                         char num[32];
288                         sprintf(num, "%d", ddls[j]);
289                         enableList += " ";
290                         enableList += num;
291                 }
292                 
293                 AliHLTReadoutList rl(enableList.Data());
294                 if (rl.Empty() == true)
295                 {
296                         cerr << "ERROR: AliHLTReadoutList::Empty returns true for a non empty readout list." << endl;
297                         return false;
298                 }
299                 
300                 // Check that the correct DDLs have been enabled and
301                 // that we can disable a DDL correctly.
302                 for (size_t j = 0; j < ddls.size(); ++j)
303                 {
304                         if (rl.IsDDLEnabled(ddls[j]) == false)
305                         {
306                                 cerr << "ERROR: DDL " << ddls[j] << " was not enabled by constructor." << endl;
307                                 return false;
308                         }
309                         rl.DisableDDLBit(ddls[j]);
310                         if (rl.IsDDLDisabled(ddls[j]) == false)
311                         {
312                                 cerr << "ERROR: AliHLTReadoutList::DisableDDLBit(x) is not working for x = "
313                                         << ddls[j] << "." << endl;
314                                 return false;
315                         }
316                 }
317                 
318                 // Fetch the raw bits for the readout list structure and check that they
319                 // are all zero, since we should have disabled everything in the loop above.
320                 AliHLTEventDDL bits = rl;
321                 for (int j = 0; j < gkAliHLTDDLListSize; ++j)
322                 {
323                         if (bits.fList[j] != 0x0)
324                         {
325                                 cerr << "ERROR: Word " << j << " in internal AliHLTReadoutList"
326                                         " bitfield structure is not zero as expected." << endl;
327                                 return false;
328                         }
329                 }
330         }
331         return true;
332 }
333
334 /**
335  * Tests if using incorrect DDL IDs returns zero or is ignored as expected.
336  */
337 bool CheckIncorrectIDs()
338 {
339         for (int i = 0; i < 1000000; ++i)
340         {
341                 // Get random DDL ID outside the valid range.
342                 int ddlid = -1;
343                 int det = gRandom->Integer(AliHLTDAQ::NumberOfDetectors()+1);
344                 if (det != AliHLTDAQ::NumberOfDetectors())
345                 {
346                         int maxddls = AliHLTDAQ::NumberOfDdls(det);
347                         int ddlindex = gRandom->Integer(0xFF - maxddls) + maxddls;
348                         ddlid = AliHLTDAQ::DdlIDOffset(det) | (ddlindex & 0xFF);
349                 }
350                 else
351                 {
352                         det = gRandom->Integer(11) + 20;
353                         if (det == 30) det = 31;
354                         int ddlindex = gRandom->Integer(0xFF);
355                         ddlid = (det << 8) | (ddlindex & 0xFF);
356                 }
357                 
358                 AliHLTReadoutList rl;
359                 if (rl.GetDDLBit(ddlid) != kFALSE)
360                 {
361                         cerr << "ERROR: Received a non zero result for invalid DDL " << ddlid << "." << endl;
362                         return false;
363                 }
364                 AliHLTEventDDL before = rl;
365                 rl.EnableDDLBit(ddlid);
366                 AliHLTEventDDL after = rl;
367                 if (memcmp(&before, &after, sizeof(AliHLTEventDDL)) != 0)
368                 {
369                         cerr << "ERROR: Modified AliHLTReadoutList structure using an invalid DDL "
370                                 << ddlid << "." << endl;
371                         cerr << "========== Dump of bits before modification ==========" << endl;
372                         for (unsigned int j = 0; j < before.fCount; ++j)
373                         {
374                                 cerr << "[word " << dec << j << "] = " << hex << before.fList[j] << dec << endl;
375                         }
376                         cerr << "========== Dump of bits after modification ==========" << endl;
377                         for (unsigned int j = 0; j < after.fCount; ++j)
378                         {
379                                 cerr << "[word " << dec << j << "] = " << hex << after.fList[j] << dec << endl;
380                         }
381                         return false;
382                 }
383         }
384         return true;
385 }
386
387 /**
388  * Runs the unit test for the AliHLTReadoutList class.
389  * \returns true if the class passed the test and false otherwise.
390  */
391 bool testAliHLTReadoutList()
392 {
393         gRandom->SetSeed(123);
394         
395         if (AliHLTDAQ::NumberOfDetectors() != kgNumberOfCodes)
396         {
397                 cerr << "ERROR: The testAliHLTReadoutList.C macro needs to be updated"
398                         " or something went really wrong."
399                         " The number of detectors reported by AliHLTDAQ is not "
400                         << kgNumberOfCodes << ", as expected, but "
401                         << AliHLTDAQ::NumberOfDetectors() << "." << endl;
402                 return false;
403         }
404         
405         if (not CheckEmptyAndClear()) return false;
406         if (not CheckEnablingDisabling()) return false;
407         if (not CheckEnablingDisablingDDLs()) return false;
408         if (not CheckIncorrectIDs()) return false;
409         
410         return true;
411 }
412
413 #ifndef __MAKECINT__
414
415 int main(int /*argc*/, const char** /*argv*/)
416 {
417         bool resultOk = testAliHLTReadoutList();
418         if (not resultOk) return 1;
419         return 0;
420 }
421
422 #endif // __MAKECINT__