]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/BASE/test/testAliHLTCTPData.C
A little task for checking the c*tau of the strange particles
[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;
231 for (int i=0; i<length; i++) {
232 unsigned char c=GetRandom(48, 83);
233 if (c>57) c+=7;
234 tcn+=c;
235 }
236 return tcn;
237}
238
239/**
240 * Generate an array of trigger classes.
241 * The array has the specified size but the number antries which are actually
242 * filled is randomized.
243 */
244int GenerateTriggerClasses(int size, vector<AliHLTCTPDataTest::AliHLTCTPTriggerClass>& classes)
245{
246 classes.clear();
247 classes.resize(size);
248 unsigned count=GetRandom(4, size>16?size/2:size);
249 for (unsigned i=0; i<count; i++) {
250 int bit=0;
251 do {
252 bit=GetRandom(0, size);
253 } while (classes[bit].Valid());
254 classes[bit].Bit(bit);
255 classes[bit].ClassName((GenerateTriggerClassName(GetRandom(5,15))).c_str());
256 unsigned nofdetectors=GetRandom(1, 10);
257 unsigned short detector=17;
258 for (unsigned k=0; k<nofdetectors; k++) {
259 detector=GetRandom(nofdetectors-k-1, detector-1);
260 classes[bit].AddDetector(detector);
261 }
262 }
263 return classes.size();
264}
265
266/**
267 * Test the CTP trigger tools
268 * The base class is initialized with an ECS string of randomly defined trigger
269 * classes consisting of random bits and names. Than a couple of expressions is
270 * test for various random bit patterns.
271 */
272int testAliHLTCTPData()
273{
274 cout << "checking AliHLTCTPData class" << endl;
275 int iResult=0;
276 vector<AliHLTCTPDataTest::AliHLTCTPTriggerClass> triggerClasses;
277 if (GenerateTriggerClasses(GetRandom(5,gkNCTPTriggerClasses), triggerClasses)<=0) {
278 return -1;
279 }
280
281 TString ecs_parameter="CONFIGURE";
282 TString ctp_parameter="CTP_TRIGGER_CLASS=";
283 vector<AliHLTCTPDataTest::AliHLTCTPTriggerClass>::iterator element=triggerClasses.begin();
284 while (element!=triggerClasses.end()) {
285 if (!element->Valid()) {
286 element=triggerClasses.erase(element);
287 continue;
288 }
289 if (!ctp_parameter.EndsWith("=")) ctp_parameter+=",";
290 if (element->Bit()<10) ctp_parameter+="0";
291 ctp_parameter+=element->Bit();
292 ctp_parameter+=":";
293 ctp_parameter+=element->ClassName(); ctp_parameter+=":";
294 ctp_parameter+=element->DetectorParam();
295 element++;
296 }
297
298 vector<const char*> parameters;
299 parameters.push_back("HLT_MODE=B");
300 parameters.push_back("RUN_NO=0");
301 parameters.push_back(ctp_parameter.Data());
302 random_shuffle(parameters.begin(), parameters.end());
303 for (vector<const char*>::iterator par=parameters.begin();
304 par!=parameters.end(); par++) {
305 ecs_parameter+=";";
306 ecs_parameter+=*par;
307 }
308
309 AliHLTCTPData ctpdata;
310 ctpdata.SetGlobalLoggingLevel(kHLTLogDefault);
311 if ((iResult=ctpdata.InitCTPTriggerClasses(ctp_parameter.Data()))<0) {
312 cerr << "InitCTPTriggerClasses failed :" << iResult << endl;
313 return iResult;
314 }
315
316 AliHLTTriggerDataAccess trigData;
317
318 // check the readout lists for the different trigger classes
319 for (element=triggerClasses.begin();
320 element!=triggerClasses.end(); element++) {
321 trigData.ResetCDH();
322 trigData.TriggerBit(element->Bit(), 1);
323 AliHLTReadoutList detectorReadout(ctpdata.ReadoutList(*trigData.Data()));
324 for (int detectorid=0; detectorid<17; detectorid++) {
325 if ((detectorReadout.DetectorEnabled(0x1<<detectorid) && !element->HasDetector(detectorid)) ||
326 (!detectorReadout.DetectorEnabled(0x1<<detectorid) && element->HasDetector(detectorid))) {
327 cerr << "readout list does not match trigger class " << element->Bit() << ":" << element->ClassName() << ":" << element->DetectorParam() << endl;
328 detectorReadout.Print();
329 return -1;
330 }
331 }
332 }
333
334 const int nofCycles=500;
335 for (int cycle=0; cycle<nofCycles && iResult>=0; cycle++) {
336 bool bHaveTrigger=false;
337 for (element=triggerClasses.begin();
338 element!=triggerClasses.end(); element++) {
339 element->Trigger(GetRandom(0,100)>50);
340 bHaveTrigger|=element->Trigger();
341 }
342 if (!bHaveTrigger) {
343 // trigger at least one class
344 (triggerClasses.begin())->Trigger(1);
345 }
346
347 vector<AliHLTCTPDataTest::AliHLTCTPTriggerClass> shuffle;
348 shuffle.assign(triggerClasses.begin(), triggerClasses.end());
349 for (unsigned int trial=0; trial<2*triggerClasses.size() && iResult>=0; trial++) {
350 random_shuffle(shuffle.begin(), shuffle.end());
351
352 bool result=0;
353 bool trigger=0;
354 TString expression;
355 trigData.ResetCDH();
356 for (element=shuffle.begin();
357 element!=shuffle.end(); element++) {
358 trigData.TriggerBit(element->Bit(), element->Trigger());
359 //cout << " " << element->Bit() << ":" << element->Trigger();
360 }
361 //cout << endl;
362
363 // single class
364 for (element=shuffle.begin();
365 element!=shuffle.end() && iResult>=0 && trial<3;
366 element++) {
367 // is
368 result=element->Trigger();
369 expression=element->ClassName();
370 trigger=ctpdata.EvaluateCTPTriggerClass(expression.Data(), *trigData.Data());
371 if (trigger!=result) {
372 cout << expression << ": " << element->Trigger()
373 << "->" << trigger
374 << std::hex << " (" << trigData.TriggerMask() << ")"
375 << endl;
376 cerr << "trigger does not match, expected " << result << endl;
377 iResult=-1;
378 break;
379 }
380
381 // is not
382 expression="!";
383 expression+=element->ClassName();
384 result=!result;
385 trigger=ctpdata.EvaluateCTPTriggerClass(expression.Data(), *trigData.Data());
386 if (trigger!=result) {
387 cout << expression << ": " << element->Trigger()
388 << "->" << trigger
389 << std::hex << " (" << trigData.TriggerMask() << ")"
390 << endl;
391 cerr << "trigger does not match, expected " << result << endl;
392 iResult=-1;
393 break;
394 }
395 }
396
397 // OR
398 result=shuffle[0].Trigger() || shuffle[1].Trigger() || shuffle[2].Trigger();
399 expression.Form("%s || %s || %s",
400 shuffle[0].ClassName(), shuffle[1].ClassName(), shuffle[2].ClassName());
401 trigger=ctpdata.EvaluateCTPTriggerClass(expression.Data(), *trigData.Data());
402 if (trigger!=result) {
403 cout << expression << ": " << shuffle[0].Trigger() << shuffle[1].Trigger() << shuffle[2].Trigger()
404 << "->" << trigger
405 << std::hex << " (" << trigData.TriggerMask() << ")"
406 << endl;
407 cerr << "trigger does not match, expected " << result << endl;
408 iResult=-1;
409 break;
410 }
411
412 // AND
413 result=shuffle[0].Trigger() && shuffle[1].Trigger() && shuffle[2].Trigger();
414 expression.Form("%s && %s && %s",
415 shuffle[0].ClassName(), shuffle[1].ClassName(), shuffle[2].ClassName());
416
417 trigger=ctpdata.EvaluateCTPTriggerClass(expression.Data(), *trigData.Data());
418 if (trigger!=result) {
419 cout << expression << ": " << shuffle[0].Trigger() << shuffle[1].Trigger() << shuffle[2].Trigger()
420 << "->" << trigger
421 << std::hex << " (" << trigData.TriggerMask() << ")"
422 << endl;
423 cerr << "trigger does not match, expected " << result << endl;
424 iResult=-1;
425 break;
426 }
427
428 // mixed OR/AND
429 result=shuffle[0].Trigger() && (shuffle[1].Trigger() || shuffle[2].Trigger());
430 expression.Form("%s && (%s || %s)",
431 shuffle[0].ClassName(), shuffle[1].ClassName(), shuffle[2].ClassName());
432
433 trigger=ctpdata.EvaluateCTPTriggerClass(expression.Data(), *trigData.Data());
434 if (trigger!=result) {
435 cout << expression << ": " << shuffle[0].Trigger() << shuffle[1].Trigger() << shuffle[2].Trigger()
436 << "->" << trigger
437 << std::hex << " (" << trigData.TriggerMask() << ")"
438 << endl;
439 cerr << "trigger does not match, expected " << result << endl;
440 iResult=-1;
441 break;
442 }
443 }
444 // readout list
445 AliHLTReadoutList detectorReadout(ctpdata.ReadoutList(*trigData.Data()));
446 for (int detectorid=0; detectorid<17 && iResult>=0; detectorid++) {
447 if (detectorReadout.DetectorEnabled(0x1<<detectorid)) {
448 // detector is included in the readout, find at least one active trigger
449 // class with this detector
450 for (element=triggerClasses.begin();
451 element!=triggerClasses.end(); element++) {
452 if (element->Trigger() && element->HasDetector(detectorid)) break;
453 }
454 if (element==triggerClasses.end()) {
455 cerr << "can not find any active trigger class for detector " << detectorid << " enabled in the readout" << endl;
456 iResult=-1;
457 }
458 } else {
459 // check that this detector is not part of any of the active trigger classes
460 for (element=triggerClasses.begin();
461 element!=triggerClasses.end(); element++) {
462 if (element->Trigger() && element->HasDetector(detectorid)) {
463 cerr << "detector " << detectorid << " not enabled in the readout but enabled in active trigger class " << element->ClassName() << endl;
464 iResult=-1;
465 }
466 }
467 }
468 if (iResult<0) {
469 detectorReadout.Print();
470 }
471 }
472 if ((cycle+1)%(nofCycles/5)==0) cout << " " << (100*(cycle+1))/nofCycles << " % done" << endl;
473 }
474
475 if (iResult<0) {
476 cerr << "check failed, dumping info" << endl;
477 cerr << "CTP param: " << ctp_parameter << endl;
478 for (element=triggerClasses.begin();
479 element!=triggerClasses.end(); element++) {
480 cerr << element->Trigger() << " " << element->Bit() << ": " << element->ClassName() << endl;
481 }
482 }
483 return iResult;
484}
485
486/////////////////////////////////////////////////////////////////////////
487/////////////////////////////////////////////////////////////////////////
488//
489// main functions
490
491int main(int /*argc*/, const char** /*argv*/)
492{
493 int iResult=0;
494 iResult=testAliHLTCTPData();
495 return iResult;
496}