Add support for opening alien files directly from the command-line, like:
[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"
27#include "TClass.h"
28#include "TNamed.h"
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()
36: TNamed("AliHLTCTPData", "HLT counters for the CTP")
37 , AliHLTLogging()
38 , fMask(0)
39 , fClassIds(TNamed::Class(), gkNCTPTriggerClasses)
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)
53 , fClassIds(TNamed::Class(), gkNCTPTriggerClasses)
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>-...,...
77 // the detector ids are ignored for the moment
78 HLTDebug(": %s", ctpString);
79 TString string=ctpString;
80 TObjArray* classEntries=string.Tokenize(",");
81 if (classEntries) {
82 for (int i=0; i<classEntries->GetEntries(); i++) {
83 TString entry=((TObjString*)classEntries->At(i))->GetString();
84 TObjArray* entryParams=entry.Tokenize(":");
85 if (entryParams) {
86 if (entryParams->GetEntries()==3 &&
87 (((TObjString*)entryParams->At(0))->GetString()).IsDigit()) {
88 int index=(((TObjString*)entryParams->At(0))->GetString()).Atoi();
89 if (index<gkNCTPTriggerClasses) {
90 fMask|=(AliHLTUInt64_t)0x1 << index;
91 ((TNamed*)fClassIds.At(index))->SetTitle("TriggerClass");
92 ((TNamed*)fClassIds.At(index))->SetName((((TObjString*)entryParams->At(1))->GetString()).Data());
93 } else {
94 // the trigger bitfield is fixed to 50 bits (gkNCTPTriggerClasses)
95 HLTError("invalid trigger class entry %s, index width of trigger bitfield", entry.Data());
96 }
97 } else {
98 HLTError("invalid trigger class entry %s", entry.Data());
99 }
100 delete entryParams;
101 }
102 }
103 delete classEntries;
104 }
105
106 ResetCounters();
107
108 return 0;
109}
110
111bool AliHLTCTPData::EvaluateCTPTriggerClass(const char* expression, AliHLTComponentTriggerData& trigData) const
112{
113 // see header file for function documentation
114 if (trigData.fDataSize != sizeof(AliHLTEventTriggerData)) {
115 HLTError("invalid trigger data size: %d expected %d", trigData.fDataSize, sizeof(AliHLTEventTriggerData));
116 return false;
117 }
118
119 // trigger mask is 50 bit wide and is stored in word 5 and 6 of the CDH
120 AliHLTEventTriggerData* evtData=reinterpret_cast<AliHLTEventTriggerData*>(trigData.fData);
121 AliHLTUInt64_t triggerMask=evtData->fCommonHeader[6];
122 triggerMask<<=32;
123 triggerMask|=evtData->fCommonHeader[5];
124
125 if (fMask!=0 && (triggerMask & fMask)==0) {
126 HLTWarning("invalid trigger mask 0x%llx, unknown CTP trigger", triggerMask);
127 return false;
128 }
129
130 // use a TFormula to interprete the expression
131 // all classname are replaced by '[n]' which means the n'th parameter in the formula
132 // the parameters are set to 0 or 1 depending on the bit in the trigger mask
133 //
134 // TODO: this will most likely fail for class names like 'base', 'baseA', 'baseB'
135 // the class names must be fully unique, none must be contained as substring in
136 // another class name. Probably not needed for the moment but needs to be extended.
137 vector<Double_t> par;
138 TString condition=expression;
139 for (int i=0; i<gkNCTPTriggerClasses; i++) {
140 const char* className=Name(i);
141 if (className && strlen(className)>0) {
142 //HLTDebug("checking trigger class %s", className.Data());
143 if (condition.Contains(className)) {
144 TString replace; replace.Form("[%d]", par.size());
145 //HLTDebug("replacing %s with %s in \"%s\"", className.Data(), replace.Data(), condition.Data());
146 condition.ReplaceAll(className, replace);
147 if (triggerMask&((AliHLTUInt64_t)0x1<<i)) par.push_back(1.0);
148 else par.push_back(0.0);
149 }
150 }
151 }
152
153 TFormula form("trigger expression", condition);
154 if (form.Compile()!=0) {
155 HLTError("invalid expression %s", expression);
156 return false;
157 }
158 if (form.EvalPar(&par[0], &par[0])>0.5) return true;
159 return false;
160}
161
162void AliHLTCTPData::ResetCounters()
163{
164 // see header file for function documentation
165 fCounters.Set(gkNCTPTriggerClasses);
166 fCounters.Reset();
167}
168
169int AliHLTCTPData::Index(const char* name) const
170{
171 // see header file for function documentation
172 TObject* obj=fClassIds.FindObject(name);
173 return obj!=NULL?fClassIds.IndexOf(obj):-1;
174}
175
176void AliHLTCTPData::Increment(const char* classIds)
177{
178 // see header file for function documentation
179 TString string=classIds;
180 TObjArray* classEntries=string.Tokenize(",");
181 if (classEntries) {
182 for (int i=0; i<classEntries->GetEntries(); i++) {
183 int index=Index(((TObjString*)classEntries->At(i))->GetString().Data());
184 if (index>=0 && index<fCounters.GetSize()) fCounters[index]++;
185 }
186 delete classEntries;
187 }
188}
189
190void AliHLTCTPData::Increment(AliHLTUInt64_t triggerPattern)
191{
192 // see header file for function documentation
193 AliHLTUInt64_t pattern=triggerPattern&fMask;
194 for (int i=0; i<fCounters.GetSize(); i++) {
195 if ((pattern&((AliHLTUInt64_t)0x1<<i))==0) continue;
196 fCounters[i]++;
197 }
198}
199
200void AliHLTCTPData::Increment(int classIdx)
201{
202 // see header file for function documentation
203 if (classIdx<fCounters.GetSize() &&
204 (fMask&((AliHLTUInt64_t)0x1<<classIdx))) {
205 fCounters[classIdx]++;
206 }
207
208}
209
210int AliHLTCTPData::Increment(AliHLTComponentTriggerData& trigData)
211{
212 // see header file for function documentation
213 if (trigData.fDataSize != sizeof(AliHLTEventTriggerData)) {
214 HLTError("invalid trigger data size: %d expected %d", trigData.fDataSize, sizeof(AliHLTEventTriggerData));
215 return -EBADF;
216 }
217
218 // trigger mask is 50 bit wide and is stored in word 5 and 6 of the CDH
219 AliHLTEventTriggerData* evtData=reinterpret_cast<AliHLTEventTriggerData*>(trigData.fData);
220 AliHLTUInt64_t triggerMask=evtData->fCommonHeader[6];
221 triggerMask<<=32;
222 triggerMask|=evtData->fCommonHeader[5];
223
224 if (fMask!=0 && (triggerMask & fMask)==0) {
225 HLTWarning("invalid trigger mask 0x%llx, unknown CTP trigger, initialized 0x%llx", triggerMask, fMask);
226 }
227 Increment(triggerMask);
228 return 0;
229}
230
231AliHLTUInt64_t AliHLTCTPData::Counter(int index) const
232{
233 // see header file for function documentation
234 if (index>=0 && index<Counters().GetSize()) return Counters()[index];
235 return 0;
236}
237
238AliHLTUInt64_t AliHLTCTPData::Counter(const char* classId) const
239{
240 // see header file for function documentation
241 return Counter(Index(classId));
242}
243
244const char* AliHLTCTPData::Name(int index) const
245{
246 // see header file for function documentation
247 if (index>fClassIds.GetLast()) return NULL;
248 return fClassIds.At(index)->GetName();
249}
250
251void AliHLTCTPData::Print(Option_t* /*option*/) const
252{
253 // see header file for function documentation
254 cout << "CTP counters:" << endl;
255 int count=0;
256 for (int i=0; i<gkNCTPTriggerClasses; i++) {
257 if (i>=Counters().GetSize()) break;
258 if (i>fClassIds.GetLast()) break;
259 if ((fMask&((AliHLTUInt64_t)0x1<<i))==0) continue;
260 count++;
261 cout << "\t" << i << "\t" << Name(i) << "\t" << Counter(i) << endl;
262 }
263 if (count==0) cout << "\t(none)" << endl;
264}