]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/BASE/test/testAliHLTCTPData.C
Fix for bug #76956: Make Info msg like 'Branch <XXX> switched [on|off]' debug messages
[u/mrichter/AliRoot.git] / HLT / BASE / test / testAliHLTCTPData.C
CommitLineData
963a5fa6 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: Matthias Richter <Matthias.Richter@ift.uib.no> *
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 testAliHLTCTPData.C
20 @author Matthias Richter
21 @date
22 @brief Test program for the AliHLTCTPData class
23 */
24
25#ifndef __CINT__
26#include "TDatime.h"
27#include "TRandom.h"
28#include "AliHLTDataTypes.h"
29#include "algorithm"
30#include "TObjArray.h"
31#include "TObjString.h"
32#include "TString.h"
33#include "AliHLTDAQ.h"
34#include <cstdio>
35#include <cstring>
36#include <iostream>
37#include <cerrno>
38#include "AliHLTCTPData.h"
39#include "AliHLTReadoutList.h"
40#endif
41
42using namespace std;
43
44class AliHLTCTPDataTest {
45public:
46 AliHLTCTPDataTest() {}
47 ~AliHLTCTPDataTest() {}
48
49 class AliHLTCTPTriggerClass {
50 public:
51 AliHLTCTPTriggerClass() : fBit(~(unsigned)0), fClassName(""), fTrigger(false), fDetectorParam(), fDetectors() {}
52 ~AliHLTCTPTriggerClass() {}
53
54 bool Valid() {return fBit!=~(unsigned)0;}
55 unsigned Bit() {return fBit;}
56 void Bit(unsigned bit) {fBit=bit;}
57 bool Trigger() {return fTrigger;}
58 void Trigger(bool trigger) {fTrigger=trigger;}
59 const char* ClassName() {return fClassName.c_str();}
60 void ClassName(const char* classname) {fClassName=classname;}
61 const char* DetectorParam() {
62 if (fDetectorParam.IsNull() && fDetectors.size()>0) {
63 for (unsigned i=0; i<fDetectors.size(); i++) {
64 if (!fDetectorParam.IsNull()) fDetectorParam+="-";
65 if (fDetectors[i]<10) fDetectorParam+="0";
66 fDetectorParam+=fDetectors[i];
67 }
68 }
69 return fDetectorParam.Data();
70 }
71 void DetectorParam(const char* detectorparam) {fDetectorParam=detectorparam;}
72 int AddDetector(unsigned short detector) {
73 fDetectorParam.Clear();
74 for (vector<unsigned short>::iterator element=fDetectors.begin();
75 element!=fDetectors.end(); element++) {
76 if (detector<*element) {
77 fDetectors.insert(element, detector);
78 return 0;
79 }
80 }
81 fDetectors.push_back(detector);
82 return 0;
83 }
84 bool HasDetector(int detector) const {
85 for (unsigned i=0; i<fDetectors.size(); i++) {
86 if (fDetectors[i]==detector) {
87 return true;
88 }
89 }
90 return false;
91 }
92 bool HasDetector(const char* id) const {
93 TString detectorid=id;
94 for (unsigned i=0; i<fDetectors.size(); i++) {
95 if (detectorid.CompareTo(AliHLTDAQ::OnlineName(fDetectors[i]))==0) {
96 return true;
97 }
98 }
99 return false;
100 }
101
102 private:
103 unsigned fBit;
104 string fClassName;
105 bool fTrigger;
106 TString fDetectorParam;
107 vector<unsigned short> fDetectors;
108 };
109
110protected:
111private:
112};
113
114class AliHLTTriggerDataAccess
115{
116public:
117 AliHLTTriggerDataAccess()
118 : fData(NULL)
119 , fEventData(NULL)
120 , fCDH(NULL)
121 , fMine(NULL)
122 {
123 unsigned size=sizeof(AliHLTComponentTriggerData) + sizeof(AliHLTEventTriggerData);
124 fMine=new Byte_t[size];
125 memset(fMine, 0, size);
126 AliHLTComponentTriggerData* data=reinterpret_cast<AliHLTComponentTriggerData*>(fMine);
127 data->fData=fMine+sizeof(AliHLTComponentTriggerData);
128 Set(data);
129 }
130
131 AliHLTTriggerDataAccess(AliHLTComponentTriggerData* pData)
132 : fData(NULL)
133 , fEventData(NULL)
134 , fCDH(NULL)
135 , fMine(NULL)
136 {
137 if (fMine) delete [] fMine;
138 fMine=NULL;
139 Set(pData);
140 }
141
142 ~AliHLTTriggerDataAccess(){
143 if (fMine) delete [] fMine;
144 fMine=NULL;
145 fData=NULL;
146 fEventData=NULL;
147 fCDH=NULL;
148 }
149
150 AliHLTComponentTriggerData* Data() {return fData;}
151
152 Long64_t TriggerMask() {
153 Long64_t mask=0;
154 if (fCDH) {
155 mask=fCDH[6];
156 mask<<=32;
157 mask|=fCDH[5];
158 }
159 return mask;
160 }
161
162 int Set(AliHLTComponentTriggerData* data) {
163 fData=data;
164 fData->fDataSize=sizeof(AliHLTEventTriggerData);
165 fEventData=reinterpret_cast<AliHLTEventTriggerData*>(fData->fData);
166 fCDH=fEventData->fCommonHeader;
167 return 0;
168 }
169
170 int ResetCDH() {
171 if (fCDH) {
172 memset(fCDH, 0, 32);
173 }
174 return 0;
175 }
176
177 int TriggerBit(unsigned bit, bool set) {
178 if ((int)bit>=gkNCTPTriggerClasses) return -EINVAL;
179 if (!fCDH) return -ENODATA;
180
181 int word=5;
182 if (bit>=32) {
183 word++;
184 bit-=32;
185 }
186 if (set)
187 fCDH[word]|=(UInt_t)0x1<<bit;
188 else
189 fCDH[word]&=~((UInt_t)0x1<<bit);
190
191 return bit;
192 }
193
194private:
195 AliHLTTriggerDataAccess(const AliHLTTriggerDataAccess&);
196 AliHLTTriggerDataAccess& operator=(const AliHLTTriggerDataAccess&);
197
198 AliHLTComponentTriggerData* fData;
199 AliHLTEventTriggerData* fEventData;
200 AliHLTUInt32_t* fCDH;
201 Byte_t* fMine;
202};
203
204/////////////////////////////////////////////////////////////////////////
205/////////////////////////////////////////////////////////////////////////
206//
207// setup of the CTP test
208
209/**
210 * Get a random number in the given range.
211 */
212int GetRandom(int min, int max)
213{
214 if (max-min<2) return min;
215 static TRandom rand;
216 static bool seedSet=false;
217 if (!seedSet) {
218 TDatime dt;
219 rand.SetSeed(dt.Get());
220 seedSet=true;
221 }
222 return min+rand.Integer(max-min);
223}
224
225/**
226 * Generate a random name of given length
227 */
228string GenerateTriggerClassName(int length)
229{
230 string tcn;
f0b885ac 231 bool toggle=false;
963a5fa6 232 for (int i=0; i<length; i++) {
f0b885ac 233 // add random number of '-' characters, but not at beginning or end
234 if (i>0 && i<length-1 && GetRandom(5,10)==7 && (toggle=(!toggle))) {
235 tcn+='-';
236 continue;
237 }
963a5fa6 238 unsigned char c=GetRandom(48, 83);
239 if (c>57) c+=7;
240 tcn+=c;
241 }
242 return tcn;
243}
244
245/**
246 * Generate an array of trigger classes.
247 * The array has the specified size but the number antries which are actually
248 * filled is randomized.
249 */
250int GenerateTriggerClasses(int size, vector<AliHLTCTPDataTest::AliHLTCTPTriggerClass>& classes)
251{
252 classes.clear();
253 classes.resize(size);
254 unsigned count=GetRandom(4, size>16?size/2:size);
f0b885ac 255 int last=-1;
963a5fa6 256 for (unsigned i=0; i<count; i++) {
257 int bit=0;
258 do {
259 bit=GetRandom(0, size);
260 } while (classes[bit].Valid());
261 classes[bit].Bit(bit);
f0b885ac 262 if (last>=0 && GetRandom(5,10)==7) {
263 // generate similar class names by just adding or truncating characters
264 string name=classes[last].ClassName();
265 if (GetRandom(0,100)%2) {
266 name+=GenerateTriggerClassName(GetRandom(3,7)).c_str();
267 cout << "using appended name " << name << " (" << classes[last].ClassName() << ")" << endl;
268 } else {
269 int num=GetRandom(1,name.length()/2);
270 name.erase(name.length()-num, num);
271 cout << "using truncated name " << name << " (" << classes[last].ClassName() << ")" << endl;
272 }
273 classes[bit].ClassName(name.c_str());
274 } else {
963a5fa6 275 classes[bit].ClassName((GenerateTriggerClassName(GetRandom(5,15))).c_str());
f0b885ac 276 }
277 last=bit;
963a5fa6 278 unsigned nofdetectors=GetRandom(1, 10);
279 unsigned short detector=17;
280 for (unsigned k=0; k<nofdetectors; k++) {
281 detector=GetRandom(nofdetectors-k-1, detector-1);
282 classes[bit].AddDetector(detector);
283 }
284 }
285 return classes.size();
286}
287
288/**
289 * Test the CTP trigger tools
290 * The base class is initialized with an ECS string of randomly defined trigger
291 * classes consisting of random bits and names. Than a couple of expressions is
292 * test for various random bit patterns.
293 */
294int testAliHLTCTPData()
295{
296 cout << "checking AliHLTCTPData class" << endl;
297 int iResult=0;
298 vector<AliHLTCTPDataTest::AliHLTCTPTriggerClass> triggerClasses;
299 if (GenerateTriggerClasses(GetRandom(5,gkNCTPTriggerClasses), triggerClasses)<=0) {
300 return -1;
301 }
302
303 TString ecs_parameter="CONFIGURE";
304 TString ctp_parameter="CTP_TRIGGER_CLASS=";
305 vector<AliHLTCTPDataTest::AliHLTCTPTriggerClass>::iterator element=triggerClasses.begin();
306 while (element!=triggerClasses.end()) {
307 if (!element->Valid()) {
308 element=triggerClasses.erase(element);
309 continue;
310 }
311 if (!ctp_parameter.EndsWith("=")) ctp_parameter+=",";
312 if (element->Bit()<10) ctp_parameter+="0";
313 ctp_parameter+=element->Bit();
314 ctp_parameter+=":";
315 ctp_parameter+=element->ClassName(); ctp_parameter+=":";
316 ctp_parameter+=element->DetectorParam();
317 element++;
318 }
319
320 vector<const char*> parameters;
321 parameters.push_back("HLT_MODE=B");
322 parameters.push_back("RUN_NO=0");
323 parameters.push_back(ctp_parameter.Data());
324 random_shuffle(parameters.begin(), parameters.end());
325 for (vector<const char*>::iterator par=parameters.begin();
326 par!=parameters.end(); par++) {
327 ecs_parameter+=";";
328 ecs_parameter+=*par;
329 }
330
331 AliHLTCTPData ctpdata;
332 ctpdata.SetGlobalLoggingLevel(kHLTLogDefault);
333 if ((iResult=ctpdata.InitCTPTriggerClasses(ctp_parameter.Data()))<0) {
334 cerr << "InitCTPTriggerClasses failed :" << iResult << endl;
335 return iResult;
336 }
337
f0b885ac 338 for (element=triggerClasses.begin();
339 element!=triggerClasses.end();
340 element++) {
341 int index=ctpdata.Index(element->ClassName());
342 if (index<0) {
343 cerr << "error: can not find CTP trigger class name " << element->ClassName() << endl;
344 return -1;
345 }
346 if (element->Bit()!=(unsigned)index) {
347 cerr << "error: wrong index for CTP trigger class " << element->ClassName() << ": expected " << element->Bit() << " - got " << index << endl;
348 return -1;
349 }
350 }
351
963a5fa6 352 AliHLTTriggerDataAccess trigData;
353
354 // check the readout lists for the different trigger classes
355 for (element=triggerClasses.begin();
356 element!=triggerClasses.end(); element++) {
357 trigData.ResetCDH();
358 trigData.TriggerBit(element->Bit(), 1);
359 AliHLTReadoutList detectorReadout(ctpdata.ReadoutList(*trigData.Data()));
360 for (int detectorid=0; detectorid<17; detectorid++) {
361 if ((detectorReadout.DetectorEnabled(0x1<<detectorid) && !element->HasDetector(detectorid)) ||
362 (!detectorReadout.DetectorEnabled(0x1<<detectorid) && element->HasDetector(detectorid))) {
363 cerr << "readout list does not match trigger class " << element->Bit() << ":" << element->ClassName() << ":" << element->DetectorParam() << endl;
364 detectorReadout.Print();
365 return -1;
366 }
367 }
368 }
369
370 const int nofCycles=500;
371 for (int cycle=0; cycle<nofCycles && iResult>=0; cycle++) {
372 bool bHaveTrigger=false;
373 for (element=triggerClasses.begin();
374 element!=triggerClasses.end(); element++) {
375 element->Trigger(GetRandom(0,100)>50);
376 bHaveTrigger|=element->Trigger();
377 }
378 if (!bHaveTrigger) {
379 // trigger at least one class
380 (triggerClasses.begin())->Trigger(1);
381 }
382
383 vector<AliHLTCTPDataTest::AliHLTCTPTriggerClass> shuffle;
384 shuffle.assign(triggerClasses.begin(), triggerClasses.end());
385 for (unsigned int trial=0; trial<2*triggerClasses.size() && iResult>=0; trial++) {
386 random_shuffle(shuffle.begin(), shuffle.end());
387
388 bool result=0;
389 bool trigger=0;
390 TString expression;
391 trigData.ResetCDH();
392 for (element=shuffle.begin();
393 element!=shuffle.end(); element++) {
394 trigData.TriggerBit(element->Bit(), element->Trigger());
395 //cout << " " << element->Bit() << ":" << element->Trigger();
396 }
397 //cout << endl;
f0b885ac 398 ctpdata.SetTriggers(*(trigData.Data()));
963a5fa6 399
400 // single class
401 for (element=shuffle.begin();
402 element!=shuffle.end() && iResult>=0 && trial<3;
403 element++) {
f0b885ac 404 int check=ctpdata.CheckTrigger(element->ClassName());
405 if (check<0) {
406 cerr << "error avaluating CheckTrigger: class name " << element->ClassName() << " not found" << endl;
407 iResult=-1;
408 break;
409 }
410 if (check!=element->Trigger()) {
411 cerr << "error avaluating CheckTrigger, class name " << element->ClassName() << ": expecting " << element->Trigger() << " - got " << check << endl;
412 ctpdata.Print();
413 iResult=-1;
414 break;
415 }
416
963a5fa6 417 // is
418 result=element->Trigger();
419 expression=element->ClassName();
420 trigger=ctpdata.EvaluateCTPTriggerClass(expression.Data(), *trigData.Data());
421 if (trigger!=result) {
422 cout << expression << ": " << element->Trigger()
423 << "->" << trigger
424 << std::hex << " (" << trigData.TriggerMask() << ")"
425 << endl;
426 cerr << "trigger does not match, expected " << result << endl;
427 iResult=-1;
428 break;
429 }
430
431 // is not
432 expression="!";
433 expression+=element->ClassName();
434 result=!result;
435 trigger=ctpdata.EvaluateCTPTriggerClass(expression.Data(), *trigData.Data());
436 if (trigger!=result) {
437 cout << expression << ": " << element->Trigger()
438 << "->" << trigger
439 << std::hex << " (" << trigData.TriggerMask() << ")"
440 << endl;
441 cerr << "trigger does not match, expected " << result << endl;
442 iResult=-1;
443 break;
444 }
445 }
446
447 // OR
448 result=shuffle[0].Trigger() || shuffle[1].Trigger() || shuffle[2].Trigger();
449 expression.Form("%s || %s || %s",
450 shuffle[0].ClassName(), shuffle[1].ClassName(), shuffle[2].ClassName());
451 trigger=ctpdata.EvaluateCTPTriggerClass(expression.Data(), *trigData.Data());
452 if (trigger!=result) {
453 cout << expression << ": " << shuffle[0].Trigger() << shuffle[1].Trigger() << shuffle[2].Trigger()
454 << "->" << trigger
455 << std::hex << " (" << trigData.TriggerMask() << ")"
456 << endl;
457 cerr << "trigger does not match, expected " << result << endl;
458 iResult=-1;
459 break;
460 }
461
462 // AND
463 result=shuffle[0].Trigger() && shuffle[1].Trigger() && shuffle[2].Trigger();
464 expression.Form("%s && %s && %s",
465 shuffle[0].ClassName(), shuffle[1].ClassName(), shuffle[2].ClassName());
466
467 trigger=ctpdata.EvaluateCTPTriggerClass(expression.Data(), *trigData.Data());
468 if (trigger!=result) {
469 cout << expression << ": " << shuffle[0].Trigger() << shuffle[1].Trigger() << shuffle[2].Trigger()
470 << "->" << trigger
471 << std::hex << " (" << trigData.TriggerMask() << ")"
472 << endl;
473 cerr << "trigger does not match, expected " << result << endl;
474 iResult=-1;
475 break;
476 }
477
478 // mixed OR/AND
479 result=shuffle[0].Trigger() && (shuffle[1].Trigger() || shuffle[2].Trigger());
480 expression.Form("%s && (%s || %s)",
481 shuffle[0].ClassName(), shuffle[1].ClassName(), shuffle[2].ClassName());
482
483 trigger=ctpdata.EvaluateCTPTriggerClass(expression.Data(), *trigData.Data());
484 if (trigger!=result) {
485 cout << expression << ": " << shuffle[0].Trigger() << shuffle[1].Trigger() << shuffle[2].Trigger()
486 << "->" << trigger
487 << std::hex << " (" << trigData.TriggerMask() << ")"
488 << endl;
489 cerr << "trigger does not match, expected " << result << endl;
490 iResult=-1;
491 break;
492 }
493 }
494 // readout list
495 AliHLTReadoutList detectorReadout(ctpdata.ReadoutList(*trigData.Data()));
496 for (int detectorid=0; detectorid<17 && iResult>=0; detectorid++) {
497 if (detectorReadout.DetectorEnabled(0x1<<detectorid)) {
498 // detector is included in the readout, find at least one active trigger
499 // class with this detector
500 for (element=triggerClasses.begin();
501 element!=triggerClasses.end(); element++) {
502 if (element->Trigger() && element->HasDetector(detectorid)) break;
503 }
504 if (element==triggerClasses.end()) {
505 cerr << "can not find any active trigger class for detector " << detectorid << " enabled in the readout" << endl;
506 iResult=-1;
507 }
508 } else {
509 // check that this detector is not part of any of the active trigger classes
510 for (element=triggerClasses.begin();
511 element!=triggerClasses.end(); element++) {
512 if (element->Trigger() && element->HasDetector(detectorid)) {
513 cerr << "detector " << detectorid << " not enabled in the readout but enabled in active trigger class " << element->ClassName() << endl;
514 iResult=-1;
515 }
516 }
517 }
518 if (iResult<0) {
519 detectorReadout.Print();
520 }
521 }
522 if ((cycle+1)%(nofCycles/5)==0) cout << " " << (100*(cycle+1))/nofCycles << " % done" << endl;
523 }
524
525 if (iResult<0) {
526 cerr << "check failed, dumping info" << endl;
527 cerr << "CTP param: " << ctp_parameter << endl;
528 for (element=triggerClasses.begin();
529 element!=triggerClasses.end(); element++) {
530 cerr << element->Trigger() << " " << element->Bit() << ": " << element->ClassName() << endl;
531 }
532 }
533 return iResult;
534}
535
536/////////////////////////////////////////////////////////////////////////
537/////////////////////////////////////////////////////////////////////////
538//
539// main functions
540
541int main(int /*argc*/, const char** /*argv*/)
542{
543 int iResult=0;
544 iResult=testAliHLTCTPData();
545 return iResult;
546}