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