bugfix: only increment CTP counters for data events, skip for SOD and EOD
[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
71 fMask=0;
72 fClassIds.Delete();
73 fClassIds.ExpandCreate(gkNCTPTriggerClasses);
74
75 // general format of the CTP_TRIGGER_CLASS parameter
76 // <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 77 HLTDebug(": %s", ctpString);
78 TString string=ctpString;
1462df14 79 if (string.BeginsWith("CTP_TRIGGER_CLASS=")) string.ReplaceAll("CTP_TRIGGER_CLASS=", "");
1dbbd625 80 TObjArray* classEntries=string.Tokenize(",");
81 if (classEntries) {
1462df14 82 enum {kBit=0, kName, kDetectors};
1dbbd625 83 for (int i=0; i<classEntries->GetEntries(); i++) {
84 TString entry=((TObjString*)classEntries->At(i))->GetString();
85 TObjArray* entryParams=entry.Tokenize(":");
86 if (entryParams) {
87 if (entryParams->GetEntries()==3 &&
1462df14 88 (((TObjString*)entryParams->At(kBit))->GetString()).IsDigit()) {
89 int index=(((TObjString*)entryParams->At(kBit))->GetString()).Atoi();
1dbbd625 90 if (index<gkNCTPTriggerClasses) {
1462df14 91 AliHLTReadoutList* pCTPClass=dynamic_cast<AliHLTReadoutList*>(fClassIds.At(index));
92 if (pCTPClass) {
93 fMask|=(AliHLTUInt64_t)0x1 << index;
94 pCTPClass->SetTitle("CTP Class");
95 pCTPClass->SetName((((TObjString*)entryParams->At(kName))->GetString()).Data());
96 TObjArray* detectors=(((TObjString*)entryParams->At(kDetectors))->GetString()).Tokenize("-");
97 if (detectors) {
98 for (int dix=0; dix<detectors->GetEntriesFast(); dix++) {
99 if (!(((TObjString*)detectors->At(dix))->GetString()).IsDigit()) {
100 HLTError("invalid detector list format: trigger class entry %s", entry.Data());
101 break;
102 }
103 // see AliHLTReadoutList::EDetectorId for defines of detectors
104 pCTPClass->Enable(0x1<<(((TObjString*)detectors->At(dix))->GetString()).Atoi());
105 }
106 delete detectors;
107 }
108 } else {
109 }
1dbbd625 110 } else {
111 // the trigger bitfield is fixed to 50 bits (gkNCTPTriggerClasses)
1462df14 112 HLTError("invalid trigger class entry %s, index width of trigger bitfield exceeded (%d)", entry.Data(), gkNCTPTriggerClasses);
1dbbd625 113 }
114 } else {
115 HLTError("invalid trigger class entry %s", entry.Data());
116 }
117 delete entryParams;
118 }
119 }
120 delete classEntries;
121 }
122
123 ResetCounters();
124
125 return 0;
126}
127
128bool AliHLTCTPData::EvaluateCTPTriggerClass(const char* expression, AliHLTComponentTriggerData& trigData) const
129{
130 // see header file for function documentation
131 if (trigData.fDataSize != sizeof(AliHLTEventTriggerData)) {
132 HLTError("invalid trigger data size: %d expected %d", trigData.fDataSize, sizeof(AliHLTEventTriggerData));
133 return false;
134 }
135
136 // trigger mask is 50 bit wide and is stored in word 5 and 6 of the CDH
137 AliHLTEventTriggerData* evtData=reinterpret_cast<AliHLTEventTriggerData*>(trigData.fData);
138 AliHLTUInt64_t triggerMask=evtData->fCommonHeader[6];
139 triggerMask<<=32;
140 triggerMask|=evtData->fCommonHeader[5];
141
142 if (fMask!=0 && (triggerMask & fMask)==0) {
143 HLTWarning("invalid trigger mask 0x%llx, unknown CTP trigger", triggerMask);
144 return false;
145 }
146
147 // use a TFormula to interprete the expression
148 // all classname are replaced by '[n]' which means the n'th parameter in the formula
149 // the parameters are set to 0 or 1 depending on the bit in the trigger mask
150 //
151 // TODO: this will most likely fail for class names like 'base', 'baseA', 'baseB'
152 // the class names must be fully unique, none must be contained as substring in
153 // another class name. Probably not needed for the moment but needs to be extended.
154 vector<Double_t> par;
155 TString condition=expression;
156 for (int i=0; i<gkNCTPTriggerClasses; i++) {
157 const char* className=Name(i);
158 if (className && strlen(className)>0) {
159 //HLTDebug("checking trigger class %s", className.Data());
160 if (condition.Contains(className)) {
161 TString replace; replace.Form("[%d]", par.size());
162 //HLTDebug("replacing %s with %s in \"%s\"", className.Data(), replace.Data(), condition.Data());
163 condition.ReplaceAll(className, replace);
164 if (triggerMask&((AliHLTUInt64_t)0x1<<i)) par.push_back(1.0);
165 else par.push_back(0.0);
166 }
167 }
168 }
169
170 TFormula form("trigger expression", condition);
171 if (form.Compile()!=0) {
172 HLTError("invalid expression %s", expression);
173 return false;
174 }
175 if (form.EvalPar(&par[0], &par[0])>0.5) return true;
176 return false;
177}
178
179void AliHLTCTPData::ResetCounters()
180{
181 // see header file for function documentation
182 fCounters.Set(gkNCTPTriggerClasses);
183 fCounters.Reset();
184}
185
186int AliHLTCTPData::Index(const char* name) const
187{
188 // see header file for function documentation
189 TObject* obj=fClassIds.FindObject(name);
190 return obj!=NULL?fClassIds.IndexOf(obj):-1;
191}
192
193void AliHLTCTPData::Increment(const char* classIds)
194{
195 // see header file for function documentation
196 TString string=classIds;
197 TObjArray* classEntries=string.Tokenize(",");
198 if (classEntries) {
199 for (int i=0; i<classEntries->GetEntries(); i++) {
200 int index=Index(((TObjString*)classEntries->At(i))->GetString().Data());
201 if (index>=0 && index<fCounters.GetSize()) fCounters[index]++;
202 }
203 delete classEntries;
204 }
205}
206
207void AliHLTCTPData::Increment(AliHLTUInt64_t triggerPattern)
208{
209 // see header file for function documentation
210 AliHLTUInt64_t pattern=triggerPattern&fMask;
211 for (int i=0; i<fCounters.GetSize(); i++) {
212 if ((pattern&((AliHLTUInt64_t)0x1<<i))==0) continue;
213 fCounters[i]++;
214 }
215}
216
217void AliHLTCTPData::Increment(int classIdx)
218{
219 // see header file for function documentation
220 if (classIdx<fCounters.GetSize() &&
221 (fMask&((AliHLTUInt64_t)0x1<<classIdx))) {
222 fCounters[classIdx]++;
223 }
224
225}
226
227int AliHLTCTPData::Increment(AliHLTComponentTriggerData& trigData)
228{
229 // see header file for function documentation
230 if (trigData.fDataSize != sizeof(AliHLTEventTriggerData)) {
231 HLTError("invalid trigger data size: %d expected %d", trigData.fDataSize, sizeof(AliHLTEventTriggerData));
232 return -EBADF;
233 }
234
235 // trigger mask is 50 bit wide and is stored in word 5 and 6 of the CDH
236 AliHLTEventTriggerData* evtData=reinterpret_cast<AliHLTEventTriggerData*>(trigData.fData);
237 AliHLTUInt64_t triggerMask=evtData->fCommonHeader[6];
238 triggerMask<<=32;
239 triggerMask|=evtData->fCommonHeader[5];
240
241 if (fMask!=0 && (triggerMask & fMask)==0) {
242 HLTWarning("invalid trigger mask 0x%llx, unknown CTP trigger, initialized 0x%llx", triggerMask, fMask);
243 }
244 Increment(triggerMask);
245 return 0;
246}
247
248AliHLTUInt64_t AliHLTCTPData::Counter(int index) const
249{
250 // see header file for function documentation
251 if (index>=0 && index<Counters().GetSize()) return Counters()[index];
252 return 0;
253}
254
255AliHLTUInt64_t AliHLTCTPData::Counter(const char* classId) const
256{
257 // see header file for function documentation
258 return Counter(Index(classId));
259}
260
261const char* AliHLTCTPData::Name(int index) const
262{
263 // see header file for function documentation
264 if (index>fClassIds.GetLast()) return NULL;
265 return fClassIds.At(index)->GetName();
266}
267
1462df14 268AliHLTEventDDL AliHLTCTPData::ReadoutList(const AliHLTComponentTriggerData& trigData) const
269{
270 // see header file for function documentation
271 if (trigData.fDataSize != sizeof(AliHLTEventTriggerData)) {
272 HLTError("invalid trigger data size: %d expected %d", trigData.fDataSize, sizeof(AliHLTEventTriggerData));
273 AliHLTEventDDL dummy;
274 memset(&dummy, 0, sizeof(AliHLTEventDDL));
275 return dummy;
276 }
277
278 // trigger mask is 50 bit wide and is stored in word 5 and 6 of the CDH
279 AliHLTEventTriggerData* evtData=reinterpret_cast<AliHLTEventTriggerData*>(trigData.fData);
280 AliHLTUInt64_t triggerMask=evtData->fCommonHeader[6];
281 triggerMask<<=32;
282 triggerMask|=evtData->fCommonHeader[5];
283
284 // take an 'OR' of all active trigger classes
285 AliHLTReadoutList list;
286 for (int i=0; i<gkNCTPTriggerClasses; i++) {
287 if (i>fClassIds.GetLast()) break;
288 if ((triggerMask&((AliHLTUInt64_t)0x1<<i))==0) continue;
289 list|=*((AliHLTReadoutList*)fClassIds.At(i));
290 }
291
292 return list;
293}
294
1dbbd625 295void AliHLTCTPData::Print(Option_t* /*option*/) const
296{
297 // see header file for function documentation
298 cout << "CTP counters:" << endl;
299 int count=0;
300 for (int i=0; i<gkNCTPTriggerClasses; i++) {
301 if (i>=Counters().GetSize()) break;
302 if (i>fClassIds.GetLast()) break;
303 if ((fMask&((AliHLTUInt64_t)0x1<<i))==0) continue;
304 count++;
305 cout << "\t" << i << "\t" << Name(i) << "\t" << Counter(i) << endl;
306 }
307 if (count==0) cout << "\t(none)" << endl;
308}