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