adding a member for the active CTP trigger mask to the CTP data object and setting...
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTCTPData.cxx
CommitLineData
1dbbd625 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> *
1dbbd625 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 AliHLTCTPData.cxx
20 @author Matthias Richter
21 @date 2009-08-20
22 @brief Container for CTP trigger classes and counters
23*/
24
25#include "AliHLTCTPData.h"
1462df14 26#include "AliHLTReadoutList.h"
1dbbd625 27#include "TClass.h"
1dbbd625 28#include "TObjString.h"
29#include "TFormula.h"
30
31/** ROOT macro for the implementation of ROOT specific class methods */
32ClassImp(AliHLTCTPData)
33
34AliHLTCTPData::AliHLTCTPData()
1462df14 35 : TNamed("AliHLTCTPData", "HLT counters for the CTP")
1dbbd625 36 , AliHLTLogging()
37 , fMask(0)
edd72347 38 , fTriggers(0)
1462df14 39 , fClassIds(AliHLTReadoutList::Class(), gkNCTPTriggerClasses)
59be6254 40 , fCounters(gkNCTPTriggerClasses)
1dbbd625 41{
42 // see header file for class documentation
43 // or
44 // refer to README to build package
45 // or
46 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
47}
48
49AliHLTCTPData::AliHLTCTPData(const char* parameter)
50 : TNamed("AliHLTCTPData", "HLT counters for the CTP")
51 , AliHLTLogging()
52 , fMask(0)
edd72347 53 , fTriggers(0)
1462df14 54 , fClassIds(AliHLTReadoutList::Class(), gkNCTPTriggerClasses)
59be6254 55 , fCounters(gkNCTPTriggerClasses)
1dbbd625 56{
57 // see header file for class documentation
58 InitCTPTriggerClasses(parameter);
59}
60
61AliHLTCTPData::~AliHLTCTPData()
62{
63 // see header file for class documentation
64 fClassIds.Delete();
65}
66
59be6254 67AliHLTCTPData::AliHLTCTPData(const AliHLTCTPData& src)
68 : TNamed(src.GetName(), src.GetTitle())
69 , AliHLTLogging()
70 , fMask(src.Mask())
edd72347 71 , fTriggers(src.fTriggers)
59be6254 72 , fClassIds(src.fClassIds)
73 , fCounters(src.Counters())
74{
75 // see header file for class documentation
76}
77
78AliHLTCTPData& AliHLTCTPData::operator=(const AliHLTCTPData& src)
79{
80 // see header file for class documentation
81 if (this!=&src) {
82 SetName(src.GetName());
83 SetTitle(src.GetTitle());
84 fMask=src.Mask();
85 fClassIds.Delete();
86 fClassIds.ExpandCreate(gkNCTPTriggerClasses);
87 for (int i=0; i<gkNCTPTriggerClasses; i++) {
88 ((TNamed*)fClassIds.At(i))->SetName(src.fClassIds.At(i)->GetName());
89 ((TNamed*)fClassIds.At(i))->SetTitle(src.fClassIds.At(i)->GetTitle());
90 }
91 fCounters=src.Counters();
92 }
93
94 return *this;
95}
96
97int AliHLTCTPData::Add(const AliHLTCTPData& src, int factor, int &skipped)
98{
99 // see header file for class documentation
100
101 skipped=0;
102 for (int i=0; i<gkNCTPTriggerClasses; i++) {
103 TString c;
104 c=fClassIds.At(i)->GetName();
105 if (c.IsNull()) continue;
106 if (c.CompareTo(src.fClassIds.At(i)->GetName())==0) {
107 fCounters[i]+=factor*src.Counter(i);
108 } else {
109 skipped++;
110 }
111 }
112 return 0;
113}
114
115AliHLTCTPData& AliHLTCTPData::operator += (const AliHLTCTPData& src)
116{
117 // see header file for class documentation
118
119 int nofInconsistencies=0;
120 Add(src, 1, nofInconsistencies);
121 if (nofInconsistencies>0) {
122 HLTError("Inconsistent operants: skipping %d of %d CTP classes for operation", nofInconsistencies, gkNCTPTriggerClasses);
123 }
124 return *this;
125}
126
127AliHLTCTPData& AliHLTCTPData::operator -= (const AliHLTCTPData& src)
128{
129 // see header file for class documentation
130
131 int nofInconsistencies=0;
132 Add(src, -1, nofInconsistencies);
133 if (nofInconsistencies>0) {
134 HLTError("Inconsistent operants: skipping %d of %d CTP classes for operation", nofInconsistencies, gkNCTPTriggerClasses);
135 }
136 return *this;
137}
138
139AliHLTCTPData AliHLTCTPData::operator + (const AliHLTCTPData& src) const
140{
141 // see header file for class documentation
142
143 AliHLTCTPData result(*this);
144 result+=src;
145 return result;
146}
147
148AliHLTCTPData AliHLTCTPData::operator - (const AliHLTCTPData& src) const
149{
150 // see header file for class documentation
151
152 AliHLTCTPData result(*this);
153 result-=src;
154 return result;
155}
156
1dbbd625 157int AliHLTCTPData::InitCTPTriggerClasses(const char* ctpString)
158{
159 // see header file for function documentation
160 if (!ctpString) return -EINVAL;
161
5be104b8 162 HLTImportant("Parameter: %s", ctpString);
163
1dbbd625 164 fMask=0;
165 fClassIds.Delete();
166 fClassIds.ExpandCreate(gkNCTPTriggerClasses);
167
168 // general format of the CTP_TRIGGER_CLASS parameter
169 // <bit position>:<Trigger class identifier string>:<detector-id-nr>-<detector-id-nr>-...,<bit position>:<Trigger class identifier string>:<detector-id-nr>-<detector-id-nr>-...,...
1dbbd625 170 HLTDebug(": %s", ctpString);
171 TString string=ctpString;
1462df14 172 if (string.BeginsWith("CTP_TRIGGER_CLASS=")) string.ReplaceAll("CTP_TRIGGER_CLASS=", "");
1dbbd625 173 TObjArray* classEntries=string.Tokenize(",");
174 if (classEntries) {
1462df14 175 enum {kBit=0, kName, kDetectors};
1dbbd625 176 for (int i=0; i<classEntries->GetEntries(); i++) {
177 TString entry=((TObjString*)classEntries->At(i))->GetString();
178 TObjArray* entryParams=entry.Tokenize(":");
179 if (entryParams) {
180 if (entryParams->GetEntries()==3 &&
1462df14 181 (((TObjString*)entryParams->At(kBit))->GetString()).IsDigit()) {
182 int index=(((TObjString*)entryParams->At(kBit))->GetString()).Atoi();
1dbbd625 183 if (index<gkNCTPTriggerClasses) {
1462df14 184 AliHLTReadoutList* pCTPClass=dynamic_cast<AliHLTReadoutList*>(fClassIds.At(index));
185 if (pCTPClass) {
186 fMask|=(AliHLTUInt64_t)0x1 << index;
187 pCTPClass->SetTitle("CTP Class");
188 pCTPClass->SetName((((TObjString*)entryParams->At(kName))->GetString()).Data());
189 TObjArray* detectors=(((TObjString*)entryParams->At(kDetectors))->GetString()).Tokenize("-");
190 if (detectors) {
191 for (int dix=0; dix<detectors->GetEntriesFast(); dix++) {
192 if (!(((TObjString*)detectors->At(dix))->GetString()).IsDigit()) {
193 HLTError("invalid detector list format: trigger class entry %s", entry.Data());
194 break;
195 }
196 // see AliHLTReadoutList::EDetectorId for defines of detectors
197 pCTPClass->Enable(0x1<<(((TObjString*)detectors->At(dix))->GetString()).Atoi());
198 }
199 delete detectors;
200 }
201 } else {
202 }
1dbbd625 203 } else {
204 // the trigger bitfield is fixed to 50 bits (gkNCTPTriggerClasses)
1462df14 205 HLTError("invalid trigger class entry %s, index width of trigger bitfield exceeded (%d)", entry.Data(), gkNCTPTriggerClasses);
1dbbd625 206 }
207 } else {
208 HLTError("invalid trigger class entry %s", entry.Data());
209 }
210 delete entryParams;
211 }
212 }
213 delete classEntries;
214 }
215
216 ResetCounters();
217
218 return 0;
219}
220
e5339167 221AliHLTUInt64_t AliHLTCTPData::ActiveTriggers(const AliHLTComponentTriggerData& trigData)
222{
223 // extract active triggers from the trigger data
224
225 if (trigData.fDataSize != sizeof(AliHLTEventTriggerData)) return (AliHLTUInt64_t)0;
226
227 // trigger mask is 50 bit wide and is stored in word 5 and 6 of the CDH
228 AliHLTEventTriggerData* evtData=reinterpret_cast<AliHLTEventTriggerData*>(trigData.fData);
229 AliHLTUInt64_t triggerMask=evtData->fCommonHeader[6]&0x3ffff;
230 triggerMask<<=32;
231 triggerMask|=evtData->fCommonHeader[5];
232 return triggerMask;
233}
234
edd72347 235bool AliHLTCTPData::EvaluateCTPTriggerClass(const char* expression, const AliHLTComponentTriggerData& trigData) const
1dbbd625 236{
237 // see header file for function documentation
238 if (trigData.fDataSize != sizeof(AliHLTEventTriggerData)) {
239 HLTError("invalid trigger data size: %d expected %d", trigData.fDataSize, sizeof(AliHLTEventTriggerData));
240 return false;
241 }
242
243 // trigger mask is 50 bit wide and is stored in word 5 and 6 of the CDH
244 AliHLTEventTriggerData* evtData=reinterpret_cast<AliHLTEventTriggerData*>(trigData.fData);
5be104b8 245 AliHLTUInt64_t triggerMask=evtData->fCommonHeader[6]&0x3ffff;
1dbbd625 246 triggerMask<<=32;
247 triggerMask|=evtData->fCommonHeader[5];
248
249 if (fMask!=0 && (triggerMask & fMask)==0) {
5be104b8 250 HLTWarning("invalid trigger mask 0x%llx, unknown CTP trigger, initialized 0x%llx", triggerMask, fMask);
251 for (int i=0; i<8; i++) HLTWarning("\t CDH[%d]=0x%lx", i, evtData->fCommonHeader[i]);
1dbbd625 252 return false;
253 }
254
edd72347 255 return EvaluateCTPTriggerClass(expression, triggerMask);
256}
257
258bool AliHLTCTPData::EvaluateCTPTriggerClass(const char* expression, AliHLTUInt64_t triggerMask) const
259{
260 // see header file for function documentation
261
1dbbd625 262 // use a TFormula to interprete the expression
263 // all classname are replaced by '[n]' which means the n'th parameter in the formula
264 // the parameters are set to 0 or 1 depending on the bit in the trigger mask
265 //
266 // TODO: this will most likely fail for class names like 'base', 'baseA', 'baseB'
267 // the class names must be fully unique, none must be contained as substring in
268 // another class name. Probably not needed for the moment but needs to be extended.
269 vector<Double_t> par;
270 TString condition=expression;
271 for (int i=0; i<gkNCTPTriggerClasses; i++) {
272 const char* className=Name(i);
273 if (className && strlen(className)>0) {
274 //HLTDebug("checking trigger class %s", className.Data());
275 if (condition.Contains(className)) {
276 TString replace; replace.Form("[%d]", par.size());
277 //HLTDebug("replacing %s with %s in \"%s\"", className.Data(), replace.Data(), condition.Data());
278 condition.ReplaceAll(className, replace);
279 if (triggerMask&((AliHLTUInt64_t)0x1<<i)) par.push_back(1.0);
280 else par.push_back(0.0);
281 }
282 }
283 }
284
285 TFormula form("trigger expression", condition);
286 if (form.Compile()!=0) {
287 HLTError("invalid expression %s", expression);
288 return false;
289 }
290 if (form.EvalPar(&par[0], &par[0])>0.5) return true;
291 return false;
292}
293
294void AliHLTCTPData::ResetCounters()
295{
296 // see header file for function documentation
297 fCounters.Set(gkNCTPTriggerClasses);
298 fCounters.Reset();
299}
300
301int AliHLTCTPData::Index(const char* name) const
302{
303 // see header file for function documentation
304 TObject* obj=fClassIds.FindObject(name);
305 return obj!=NULL?fClassIds.IndexOf(obj):-1;
306}
307
308void AliHLTCTPData::Increment(const char* classIds)
309{
310 // see header file for function documentation
311 TString string=classIds;
312 TObjArray* classEntries=string.Tokenize(",");
313 if (classEntries) {
314 for (int i=0; i<classEntries->GetEntries(); i++) {
315 int index=Index(((TObjString*)classEntries->At(i))->GetString().Data());
316 if (index>=0 && index<fCounters.GetSize()) fCounters[index]++;
317 }
318 delete classEntries;
319 }
320}
321
322void AliHLTCTPData::Increment(AliHLTUInt64_t triggerPattern)
323{
324 // see header file for function documentation
325 AliHLTUInt64_t pattern=triggerPattern&fMask;
326 for (int i=0; i<fCounters.GetSize(); i++) {
327 if ((pattern&((AliHLTUInt64_t)0x1<<i))==0) continue;
328 fCounters[i]++;
329 }
330}
331
332void AliHLTCTPData::Increment(int classIdx)
333{
334 // see header file for function documentation
335 if (classIdx<fCounters.GetSize() &&
336 (fMask&((AliHLTUInt64_t)0x1<<classIdx))) {
337 fCounters[classIdx]++;
338 }
339
340}
341
342int AliHLTCTPData::Increment(AliHLTComponentTriggerData& trigData)
343{
344 // see header file for function documentation
345 if (trigData.fDataSize != sizeof(AliHLTEventTriggerData)) {
346 HLTError("invalid trigger data size: %d expected %d", trigData.fDataSize, sizeof(AliHLTEventTriggerData));
347 return -EBADF;
348 }
349
350 // trigger mask is 50 bit wide and is stored in word 5 and 6 of the CDH
351 AliHLTEventTriggerData* evtData=reinterpret_cast<AliHLTEventTriggerData*>(trigData.fData);
5be104b8 352 AliHLTUInt64_t triggerMask=evtData->fCommonHeader[6]&0x3ffff;
1dbbd625 353 triggerMask<<=32;
354 triggerMask|=evtData->fCommonHeader[5];
355
356 if (fMask!=0 && (triggerMask & fMask)==0) {
357 HLTWarning("invalid trigger mask 0x%llx, unknown CTP trigger, initialized 0x%llx", triggerMask, fMask);
5be104b8 358 for (int i=0; i<8; i++) HLTWarning("\t CDH[%d]=0x%lx", i, evtData->fCommonHeader[i]);
1dbbd625 359 }
360 Increment(triggerMask);
361 return 0;
362}
363
364AliHLTUInt64_t AliHLTCTPData::Counter(int index) const
365{
366 // see header file for function documentation
367 if (index>=0 && index<Counters().GetSize()) return Counters()[index];
368 return 0;
369}
370
371AliHLTUInt64_t AliHLTCTPData::Counter(const char* classId) const
372{
373 // see header file for function documentation
374 return Counter(Index(classId));
375}
376
377const char* AliHLTCTPData::Name(int index) const
378{
379 // see header file for function documentation
380 if (index>fClassIds.GetLast()) return NULL;
381 return fClassIds.At(index)->GetName();
382}
383
1462df14 384AliHLTEventDDL AliHLTCTPData::ReadoutList(const AliHLTComponentTriggerData& trigData) const
385{
386 // see header file for function documentation
387 if (trigData.fDataSize != sizeof(AliHLTEventTriggerData)) {
388 HLTError("invalid trigger data size: %d expected %d", trigData.fDataSize, sizeof(AliHLTEventTriggerData));
389 AliHLTEventDDL dummy;
390 memset(&dummy, 0, sizeof(AliHLTEventDDL));
391 return dummy;
392 }
393
394 // trigger mask is 50 bit wide and is stored in word 5 and 6 of the CDH
395 AliHLTEventTriggerData* evtData=reinterpret_cast<AliHLTEventTriggerData*>(trigData.fData);
5be104b8 396 AliHLTUInt64_t triggerMask=evtData->fCommonHeader[6]&0x3ffff;
1462df14 397 triggerMask<<=32;
398 triggerMask|=evtData->fCommonHeader[5];
399
5be104b8 400 if (fMask!=0 && (triggerMask & fMask)==0) {
401 HLTWarning("invalid trigger mask 0x%llx, unknown CTP trigger, initialized 0x%llx", triggerMask, fMask);
402 for (int i=0; i<8; i++) HLTWarning("\t CDH[%d]=0x%lx", i, evtData->fCommonHeader[i]);
403 }
404
1462df14 405 // take an 'OR' of all active trigger classes
406 AliHLTReadoutList list;
407 for (int i=0; i<gkNCTPTriggerClasses; i++) {
408 if (i>fClassIds.GetLast()) break;
409 if ((triggerMask&((AliHLTUInt64_t)0x1<<i))==0) continue;
5be104b8 410 AliHLTReadoutList* tcrl=(AliHLTReadoutList*)fClassIds.At(i);
45398383 411 list.OrEq(*tcrl);
1462df14 412 }
413
414 return list;
415}
416
1dbbd625 417void AliHLTCTPData::Print(Option_t* /*option*/) const
418{
419 // see header file for function documentation
59be6254 420 cout << GetTitle() << endl;
edd72347 421 cout << "\tactive trigger mask: 0x" << hex << fTriggers << dec << endl;
1dbbd625 422 int count=0;
423 for (int i=0; i<gkNCTPTriggerClasses; i++) {
424 if (i>=Counters().GetSize()) break;
425 if (i>fClassIds.GetLast()) break;
426 if ((fMask&((AliHLTUInt64_t)0x1<<i))==0) continue;
427 count++;
428 cout << "\t" << i << "\t" << Name(i) << "\t" << Counter(i) << endl;
429 }
430 if (count==0) cout << "\t(none)" << endl;
431}