cleaning up AliHLTRunStatistics class to be used as a container for run statistics...
[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> *
8//* Timm Steinbeck <timm@kip.uni-heidelberg.de> *
9//* for The ALICE HLT Project. *
10//* *
11//* Permission to use, copy, modify and distribute this software and its *
12//* documentation strictly for non-commercial purposes is hereby granted *
13//* without fee, provided that the above copyright notice appears in all *
14//* copies and that both the copyright notice and this permission notice *
15//* appear in the supporting documentation. The authors make no claims *
16//* about the suitability of this software for any purpose. It is *
17//* provided "as is" without express or implied warranty. *
18//**************************************************************************
19
20/** @file AliHLTCTPData.cxx
21 @author Matthias Richter
22 @date 2009-08-20
23 @brief Container for CTP trigger classes and counters
24*/
25
26#include "AliHLTCTPData.h"
1462df14 27#include "AliHLTReadoutList.h"
1dbbd625 28#include "TClass.h"
1dbbd625 29#include "TObjString.h"
30#include "TFormula.h"
31
32/** ROOT macro for the implementation of ROOT specific class methods */
33ClassImp(AliHLTCTPData)
34
35AliHLTCTPData::AliHLTCTPData()
1462df14 36 : TNamed("AliHLTCTPData", "HLT counters for the CTP")
1dbbd625 37 , AliHLTLogging()
38 , fMask(0)
1462df14 39 , fClassIds(AliHLTReadoutList::Class(), gkNCTPTriggerClasses)
1dbbd625 40 , fCounters()
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)
1462df14 53 , fClassIds(AliHLTReadoutList::Class(), gkNCTPTriggerClasses)
1dbbd625 54 , fCounters()
55{
56 // see header file for class documentation
57 InitCTPTriggerClasses(parameter);
58}
59
60AliHLTCTPData::~AliHLTCTPData()
61{
62 // see header file for class documentation
63 fClassIds.Delete();
64}
65
66int AliHLTCTPData::InitCTPTriggerClasses(const char* ctpString)
67{
68 // see header file for function documentation
69 if (!ctpString) return -EINVAL;
70
5be104b8 71 HLTImportant("Parameter: %s", ctpString);
72
1dbbd625 73 fMask=0;
74 fClassIds.Delete();
75 fClassIds.ExpandCreate(gkNCTPTriggerClasses);
76
77 // general format of the CTP_TRIGGER_CLASS parameter
78 // <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 79 HLTDebug(": %s", ctpString);
80 TString string=ctpString;
1462df14 81 if (string.BeginsWith("CTP_TRIGGER_CLASS=")) string.ReplaceAll("CTP_TRIGGER_CLASS=", "");
1dbbd625 82 TObjArray* classEntries=string.Tokenize(",");
83 if (classEntries) {
1462df14 84 enum {kBit=0, kName, kDetectors};
1dbbd625 85 for (int i=0; i<classEntries->GetEntries(); i++) {
86 TString entry=((TObjString*)classEntries->At(i))->GetString();
87 TObjArray* entryParams=entry.Tokenize(":");
88 if (entryParams) {
89 if (entryParams->GetEntries()==3 &&
1462df14 90 (((TObjString*)entryParams->At(kBit))->GetString()).IsDigit()) {
91 int index=(((TObjString*)entryParams->At(kBit))->GetString()).Atoi();
1dbbd625 92 if (index<gkNCTPTriggerClasses) {
1462df14 93 AliHLTReadoutList* pCTPClass=dynamic_cast<AliHLTReadoutList*>(fClassIds.At(index));
94 if (pCTPClass) {
95 fMask|=(AliHLTUInt64_t)0x1 << index;
96 pCTPClass->SetTitle("CTP Class");
97 pCTPClass->SetName((((TObjString*)entryParams->At(kName))->GetString()).Data());
98 TObjArray* detectors=(((TObjString*)entryParams->At(kDetectors))->GetString()).Tokenize("-");
99 if (detectors) {
100 for (int dix=0; dix<detectors->GetEntriesFast(); dix++) {
101 if (!(((TObjString*)detectors->At(dix))->GetString()).IsDigit()) {
102 HLTError("invalid detector list format: trigger class entry %s", entry.Data());
103 break;
104 }
105 // see AliHLTReadoutList::EDetectorId for defines of detectors
106 pCTPClass->Enable(0x1<<(((TObjString*)detectors->At(dix))->GetString()).Atoi());
107 }
108 delete detectors;
109 }
110 } else {
111 }
1dbbd625 112 } else {
113 // the trigger bitfield is fixed to 50 bits (gkNCTPTriggerClasses)
1462df14 114 HLTError("invalid trigger class entry %s, index width of trigger bitfield exceeded (%d)", entry.Data(), gkNCTPTriggerClasses);
1dbbd625 115 }
116 } else {
117 HLTError("invalid trigger class entry %s", entry.Data());
118 }
119 delete entryParams;
120 }
121 }
122 delete classEntries;
123 }
124
125 ResetCounters();
126
127 return 0;
128}
129
130bool AliHLTCTPData::EvaluateCTPTriggerClass(const char* expression, AliHLTComponentTriggerData& trigData) const
131{
132 // see header file for function documentation
133 if (trigData.fDataSize != sizeof(AliHLTEventTriggerData)) {
134 HLTError("invalid trigger data size: %d expected %d", trigData.fDataSize, sizeof(AliHLTEventTriggerData));
135 return false;
136 }
137
138 // trigger mask is 50 bit wide and is stored in word 5 and 6 of the CDH
139 AliHLTEventTriggerData* evtData=reinterpret_cast<AliHLTEventTriggerData*>(trigData.fData);
5be104b8 140 AliHLTUInt64_t triggerMask=evtData->fCommonHeader[6]&0x3ffff;
1dbbd625 141 triggerMask<<=32;
142 triggerMask|=evtData->fCommonHeader[5];
143
144 if (fMask!=0 && (triggerMask & fMask)==0) {
5be104b8 145 HLTWarning("invalid trigger mask 0x%llx, unknown CTP trigger, initialized 0x%llx", triggerMask, fMask);
146 for (int i=0; i<8; i++) HLTWarning("\t CDH[%d]=0x%lx", i, evtData->fCommonHeader[i]);
1dbbd625 147 return false;
148 }
149
150 // use a TFormula to interprete the expression
151 // all classname are replaced by '[n]' which means the n'th parameter in the formula
152 // the parameters are set to 0 or 1 depending on the bit in the trigger mask
153 //
154 // TODO: this will most likely fail for class names like 'base', 'baseA', 'baseB'
155 // the class names must be fully unique, none must be contained as substring in
156 // another class name. Probably not needed for the moment but needs to be extended.
157 vector<Double_t> par;
158 TString condition=expression;
159 for (int i=0; i<gkNCTPTriggerClasses; i++) {
160 const char* className=Name(i);
161 if (className && strlen(className)>0) {
162 //HLTDebug("checking trigger class %s", className.Data());
163 if (condition.Contains(className)) {
164 TString replace; replace.Form("[%d]", par.size());
165 //HLTDebug("replacing %s with %s in \"%s\"", className.Data(), replace.Data(), condition.Data());
166 condition.ReplaceAll(className, replace);
167 if (triggerMask&((AliHLTUInt64_t)0x1<<i)) par.push_back(1.0);
168 else par.push_back(0.0);
169 }
170 }
171 }
172
173 TFormula form("trigger expression", condition);
174 if (form.Compile()!=0) {
175 HLTError("invalid expression %s", expression);
176 return false;
177 }
178 if (form.EvalPar(&par[0], &par[0])>0.5) return true;
179 return false;
180}
181
182void AliHLTCTPData::ResetCounters()
183{
184 // see header file for function documentation
185 fCounters.Set(gkNCTPTriggerClasses);
186 fCounters.Reset();
187}
188
189int AliHLTCTPData::Index(const char* name) const
190{
191 // see header file for function documentation
192 TObject* obj=fClassIds.FindObject(name);
193 return obj!=NULL?fClassIds.IndexOf(obj):-1;
194}
195
196void AliHLTCTPData::Increment(const char* classIds)
197{
198 // see header file for function documentation
199 TString string=classIds;
200 TObjArray* classEntries=string.Tokenize(",");
201 if (classEntries) {
202 for (int i=0; i<classEntries->GetEntries(); i++) {
203 int index=Index(((TObjString*)classEntries->At(i))->GetString().Data());
204 if (index>=0 && index<fCounters.GetSize()) fCounters[index]++;
205 }
206 delete classEntries;
207 }
208}
209
210void AliHLTCTPData::Increment(AliHLTUInt64_t triggerPattern)
211{
212 // see header file for function documentation
213 AliHLTUInt64_t pattern=triggerPattern&fMask;
214 for (int i=0; i<fCounters.GetSize(); i++) {
215 if ((pattern&((AliHLTUInt64_t)0x1<<i))==0) continue;
216 fCounters[i]++;
217 }
218}
219
220void AliHLTCTPData::Increment(int classIdx)
221{
222 // see header file for function documentation
223 if (classIdx<fCounters.GetSize() &&
224 (fMask&((AliHLTUInt64_t)0x1<<classIdx))) {
225 fCounters[classIdx]++;
226 }
227
228}
229
230int AliHLTCTPData::Increment(AliHLTComponentTriggerData& trigData)
231{
232 // see header file for function documentation
233 if (trigData.fDataSize != sizeof(AliHLTEventTriggerData)) {
234 HLTError("invalid trigger data size: %d expected %d", trigData.fDataSize, sizeof(AliHLTEventTriggerData));
235 return -EBADF;
236 }
237
238 // trigger mask is 50 bit wide and is stored in word 5 and 6 of the CDH
239 AliHLTEventTriggerData* evtData=reinterpret_cast<AliHLTEventTriggerData*>(trigData.fData);
5be104b8 240 AliHLTUInt64_t triggerMask=evtData->fCommonHeader[6]&0x3ffff;
1dbbd625 241 triggerMask<<=32;
242 triggerMask|=evtData->fCommonHeader[5];
243
244 if (fMask!=0 && (triggerMask & fMask)==0) {
245 HLTWarning("invalid trigger mask 0x%llx, unknown CTP trigger, initialized 0x%llx", triggerMask, fMask);
5be104b8 246 for (int i=0; i<8; i++) HLTWarning("\t CDH[%d]=0x%lx", i, evtData->fCommonHeader[i]);
1dbbd625 247 }
248 Increment(triggerMask);
249 return 0;
250}
251
252AliHLTUInt64_t AliHLTCTPData::Counter(int index) const
253{
254 // see header file for function documentation
255 if (index>=0 && index<Counters().GetSize()) return Counters()[index];
256 return 0;
257}
258
259AliHLTUInt64_t AliHLTCTPData::Counter(const char* classId) const
260{
261 // see header file for function documentation
262 return Counter(Index(classId));
263}
264
265const char* AliHLTCTPData::Name(int index) const
266{
267 // see header file for function documentation
268 if (index>fClassIds.GetLast()) return NULL;
269 return fClassIds.At(index)->GetName();
270}
271
1462df14 272AliHLTEventDDL AliHLTCTPData::ReadoutList(const AliHLTComponentTriggerData& trigData) const
273{
274 // see header file for function documentation
275 if (trigData.fDataSize != sizeof(AliHLTEventTriggerData)) {
276 HLTError("invalid trigger data size: %d expected %d", trigData.fDataSize, sizeof(AliHLTEventTriggerData));
277 AliHLTEventDDL dummy;
278 memset(&dummy, 0, sizeof(AliHLTEventDDL));
279 return dummy;
280 }
281
282 // trigger mask is 50 bit wide and is stored in word 5 and 6 of the CDH
283 AliHLTEventTriggerData* evtData=reinterpret_cast<AliHLTEventTriggerData*>(trigData.fData);
5be104b8 284 AliHLTUInt64_t triggerMask=evtData->fCommonHeader[6]&0x3ffff;
1462df14 285 triggerMask<<=32;
286 triggerMask|=evtData->fCommonHeader[5];
287
5be104b8 288 if (fMask!=0 && (triggerMask & fMask)==0) {
289 HLTWarning("invalid trigger mask 0x%llx, unknown CTP trigger, initialized 0x%llx", triggerMask, fMask);
290 for (int i=0; i<8; i++) HLTWarning("\t CDH[%d]=0x%lx", i, evtData->fCommonHeader[i]);
291 }
292
1462df14 293 // take an 'OR' of all active trigger classes
294 AliHLTReadoutList list;
295 for (int i=0; i<gkNCTPTriggerClasses; i++) {
296 if (i>fClassIds.GetLast()) break;
297 if ((triggerMask&((AliHLTUInt64_t)0x1<<i))==0) continue;
5be104b8 298 AliHLTReadoutList* tcrl=(AliHLTReadoutList*)fClassIds.At(i);
299 // 2009-08-27: this is a temorary bugfix:
300 // the operator functions of the AliHLTReadoutList class did not work
301 // when running online on the HLT cluster. The fix for the moment is
302 // to send out the readout list only for the first matching trigger
303 // class instead of merging the list. This is sufficient for the
304 // current trigger setups but needs to be corrected
305 return *tcrl;
306 list|=*tcrl;
1462df14 307 }
308
309 return list;
310}
311
1dbbd625 312void AliHLTCTPData::Print(Option_t* /*option*/) const
313{
314 // see header file for function documentation
315 cout << "CTP counters:" << endl;
316 int count=0;
317 for (int i=0; i<gkNCTPTriggerClasses; i++) {
318 if (i>=Counters().GetSize()) break;
319 if (i>fClassIds.GetLast()) break;
320 if ((fMask&((AliHLTUInt64_t)0x1<<i))==0) continue;
321 count++;
322 cout << "\t" << i << "\t" << Name(i) << "\t" << Counter(i) << endl;
323 }
324 if (count==0) cout << "\t(none)" << endl;
325}