3 //**************************************************************************
4 //* This file is property of and copyright by the ALICE HLT Project *
5 //* ALICE Experiment at CERN, All rights reserved. *
7 //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8 //* for The ALICE HLT Project. *
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 //**************************************************************************
19 /** @file AliHLTCTPData.cxx
20 @author Matthias Richter
22 @brief Container for CTP trigger classes and counters
25 #include "AliHLTCTPData.h"
26 #include "AliHLTReadoutList.h"
28 #include "TObjString.h"
31 /** ROOT macro for the implementation of ROOT specific class methods */
32 ClassImp(AliHLTCTPData)
34 AliHLTCTPData::AliHLTCTPData()
35 : TNamed("AliHLTCTPData", "HLT counters for the CTP")
38 , fClassIds(AliHLTReadoutList::Class(), gkNCTPTriggerClasses)
39 , fCounters(gkNCTPTriggerClasses)
41 // see header file for class documentation
43 // refer to README to build package
45 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
48 AliHLTCTPData::AliHLTCTPData(const char* parameter)
49 : TNamed("AliHLTCTPData", "HLT counters for the CTP")
52 , fClassIds(AliHLTReadoutList::Class(), gkNCTPTriggerClasses)
53 , fCounters(gkNCTPTriggerClasses)
55 // see header file for class documentation
56 InitCTPTriggerClasses(parameter);
59 AliHLTCTPData::~AliHLTCTPData()
61 // see header file for class documentation
65 AliHLTCTPData::AliHLTCTPData(const AliHLTCTPData& src)
66 : TNamed(src.GetName(), src.GetTitle())
69 , fClassIds(src.fClassIds)
70 , fCounters(src.Counters())
72 // see header file for class documentation
75 AliHLTCTPData& AliHLTCTPData::operator=(const AliHLTCTPData& src)
77 // see header file for class documentation
79 SetName(src.GetName());
80 SetTitle(src.GetTitle());
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());
88 fCounters=src.Counters();
94 int AliHLTCTPData::Add(const AliHLTCTPData& src, int factor, int &skipped)
96 // see header file for class documentation
99 for (int i=0; i<gkNCTPTriggerClasses; i++) {
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);
112 AliHLTCTPData& AliHLTCTPData::operator += (const AliHLTCTPData& src)
114 // see header file for class documentation
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);
124 AliHLTCTPData& AliHLTCTPData::operator -= (const AliHLTCTPData& src)
126 // see header file for class documentation
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);
136 AliHLTCTPData AliHLTCTPData::operator + (const AliHLTCTPData& src) const
138 // see header file for class documentation
140 AliHLTCTPData result(*this);
145 AliHLTCTPData AliHLTCTPData::operator - (const AliHLTCTPData& src) const
147 // see header file for class documentation
149 AliHLTCTPData result(*this);
154 int AliHLTCTPData::InitCTPTriggerClasses(const char* ctpString)
156 // see header file for function documentation
157 if (!ctpString) return -EINVAL;
159 HLTImportant("Parameter: %s", ctpString);
163 fClassIds.ExpandCreate(gkNCTPTriggerClasses);
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>-...,...
167 HLTDebug(": %s", ctpString);
168 TString string=ctpString;
169 if (string.BeginsWith("CTP_TRIGGER_CLASS=")) string.ReplaceAll("CTP_TRIGGER_CLASS=", "");
170 TObjArray* classEntries=string.Tokenize(",");
172 enum {kBit=0, kName, kDetectors};
173 for (int i=0; i<classEntries->GetEntries(); i++) {
174 TString entry=((TObjString*)classEntries->At(i))->GetString();
175 TObjArray* entryParams=entry.Tokenize(":");
177 if (entryParams->GetEntries()==3 &&
178 (((TObjString*)entryParams->At(kBit))->GetString()).IsDigit()) {
179 int index=(((TObjString*)entryParams->At(kBit))->GetString()).Atoi();
180 if (index<gkNCTPTriggerClasses) {
181 AliHLTReadoutList* pCTPClass=dynamic_cast<AliHLTReadoutList*>(fClassIds.At(index));
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("-");
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());
193 // see AliHLTReadoutList::EDetectorId for defines of detectors
194 pCTPClass->Enable(0x1<<(((TObjString*)detectors->At(dix))->GetString()).Atoi());
201 // the trigger bitfield is fixed to 50 bits (gkNCTPTriggerClasses)
202 HLTError("invalid trigger class entry %s, index width of trigger bitfield exceeded (%d)", entry.Data(), gkNCTPTriggerClasses);
205 HLTError("invalid trigger class entry %s", entry.Data());
218 bool AliHLTCTPData::EvaluateCTPTriggerClass(const char* expression, AliHLTComponentTriggerData& trigData) const
220 // see header file for function documentation
221 if (trigData.fDataSize != sizeof(AliHLTEventTriggerData)) {
222 HLTError("invalid trigger data size: %d expected %d", trigData.fDataSize, sizeof(AliHLTEventTriggerData));
226 // trigger mask is 50 bit wide and is stored in word 5 and 6 of the CDH
227 AliHLTEventTriggerData* evtData=reinterpret_cast<AliHLTEventTriggerData*>(trigData.fData);
228 AliHLTUInt64_t triggerMask=evtData->fCommonHeader[6]&0x3ffff;
230 triggerMask|=evtData->fCommonHeader[5];
232 if (fMask!=0 && (triggerMask & fMask)==0) {
233 HLTWarning("invalid trigger mask 0x%llx, unknown CTP trigger, initialized 0x%llx", triggerMask, fMask);
234 for (int i=0; i<8; i++) HLTWarning("\t CDH[%d]=0x%lx", i, evtData->fCommonHeader[i]);
238 // use a TFormula to interprete the expression
239 // all classname are replaced by '[n]' which means the n'th parameter in the formula
240 // the parameters are set to 0 or 1 depending on the bit in the trigger mask
242 // TODO: this will most likely fail for class names like 'base', 'baseA', 'baseB'
243 // the class names must be fully unique, none must be contained as substring in
244 // another class name. Probably not needed for the moment but needs to be extended.
245 vector<Double_t> par;
246 TString condition=expression;
247 for (int i=0; i<gkNCTPTriggerClasses; i++) {
248 const char* className=Name(i);
249 if (className && strlen(className)>0) {
250 //HLTDebug("checking trigger class %s", className.Data());
251 if (condition.Contains(className)) {
252 TString replace; replace.Form("[%d]", par.size());
253 //HLTDebug("replacing %s with %s in \"%s\"", className.Data(), replace.Data(), condition.Data());
254 condition.ReplaceAll(className, replace);
255 if (triggerMask&((AliHLTUInt64_t)0x1<<i)) par.push_back(1.0);
256 else par.push_back(0.0);
261 TFormula form("trigger expression", condition);
262 if (form.Compile()!=0) {
263 HLTError("invalid expression %s", expression);
266 if (form.EvalPar(&par[0], &par[0])>0.5) return true;
270 void AliHLTCTPData::ResetCounters()
272 // see header file for function documentation
273 fCounters.Set(gkNCTPTriggerClasses);
277 int AliHLTCTPData::Index(const char* name) const
279 // see header file for function documentation
280 TObject* obj=fClassIds.FindObject(name);
281 return obj!=NULL?fClassIds.IndexOf(obj):-1;
284 void AliHLTCTPData::Increment(const char* classIds)
286 // see header file for function documentation
287 TString string=classIds;
288 TObjArray* classEntries=string.Tokenize(",");
290 for (int i=0; i<classEntries->GetEntries(); i++) {
291 int index=Index(((TObjString*)classEntries->At(i))->GetString().Data());
292 if (index>=0 && index<fCounters.GetSize()) fCounters[index]++;
298 void AliHLTCTPData::Increment(AliHLTUInt64_t triggerPattern)
300 // see header file for function documentation
301 AliHLTUInt64_t pattern=triggerPattern&fMask;
302 for (int i=0; i<fCounters.GetSize(); i++) {
303 if ((pattern&((AliHLTUInt64_t)0x1<<i))==0) continue;
308 void AliHLTCTPData::Increment(int classIdx)
310 // see header file for function documentation
311 if (classIdx<fCounters.GetSize() &&
312 (fMask&((AliHLTUInt64_t)0x1<<classIdx))) {
313 fCounters[classIdx]++;
318 int AliHLTCTPData::Increment(AliHLTComponentTriggerData& trigData)
320 // see header file for function documentation
321 if (trigData.fDataSize != sizeof(AliHLTEventTriggerData)) {
322 HLTError("invalid trigger data size: %d expected %d", trigData.fDataSize, sizeof(AliHLTEventTriggerData));
326 // trigger mask is 50 bit wide and is stored in word 5 and 6 of the CDH
327 AliHLTEventTriggerData* evtData=reinterpret_cast<AliHLTEventTriggerData*>(trigData.fData);
328 AliHLTUInt64_t triggerMask=evtData->fCommonHeader[6]&0x3ffff;
330 triggerMask|=evtData->fCommonHeader[5];
332 if (fMask!=0 && (triggerMask & fMask)==0) {
333 HLTWarning("invalid trigger mask 0x%llx, unknown CTP trigger, initialized 0x%llx", triggerMask, fMask);
334 for (int i=0; i<8; i++) HLTWarning("\t CDH[%d]=0x%lx", i, evtData->fCommonHeader[i]);
336 Increment(triggerMask);
340 AliHLTUInt64_t AliHLTCTPData::Counter(int index) const
342 // see header file for function documentation
343 if (index>=0 && index<Counters().GetSize()) return Counters()[index];
347 AliHLTUInt64_t AliHLTCTPData::Counter(const char* classId) const
349 // see header file for function documentation
350 return Counter(Index(classId));
353 const char* AliHLTCTPData::Name(int index) const
355 // see header file for function documentation
356 if (index>fClassIds.GetLast()) return NULL;
357 return fClassIds.At(index)->GetName();
360 AliHLTEventDDL AliHLTCTPData::ReadoutList(const AliHLTComponentTriggerData& trigData) const
362 // see header file for function documentation
363 if (trigData.fDataSize != sizeof(AliHLTEventTriggerData)) {
364 HLTError("invalid trigger data size: %d expected %d", trigData.fDataSize, sizeof(AliHLTEventTriggerData));
365 AliHLTEventDDL dummy;
366 memset(&dummy, 0, sizeof(AliHLTEventDDL));
370 // trigger mask is 50 bit wide and is stored in word 5 and 6 of the CDH
371 AliHLTEventTriggerData* evtData=reinterpret_cast<AliHLTEventTriggerData*>(trigData.fData);
372 AliHLTUInt64_t triggerMask=evtData->fCommonHeader[6]&0x3ffff;
374 triggerMask|=evtData->fCommonHeader[5];
376 if (fMask!=0 && (triggerMask & fMask)==0) {
377 HLTWarning("invalid trigger mask 0x%llx, unknown CTP trigger, initialized 0x%llx", triggerMask, fMask);
378 for (int i=0; i<8; i++) HLTWarning("\t CDH[%d]=0x%lx", i, evtData->fCommonHeader[i]);
381 // take an 'OR' of all active trigger classes
382 AliHLTReadoutList list;
383 for (int i=0; i<gkNCTPTriggerClasses; i++) {
384 if (i>fClassIds.GetLast()) break;
385 if ((triggerMask&((AliHLTUInt64_t)0x1<<i))==0) continue;
386 AliHLTReadoutList* tcrl=(AliHLTReadoutList*)fClassIds.At(i);
387 // 2009-08-27: this is a temorary bugfix:
388 // the operator functions of the AliHLTReadoutList class did not work
389 // when running online on the HLT cluster. The fix for the moment is
390 // to send out the readout list only for the first matching trigger
391 // class instead of merging the list. This is sufficient for the
392 // current trigger setups but needs to be corrected
400 void AliHLTCTPData::Print(Option_t* /*option*/) const
402 // see header file for function documentation
403 cout << GetTitle() << endl;
405 for (int i=0; i<gkNCTPTriggerClasses; i++) {
406 if (i>=Counters().GetSize()) break;
407 if (i>fClassIds.GetLast()) break;
408 if ((fMask&((AliHLTUInt64_t)0x1<<i))==0) continue;
410 cout << "\t" << i << "\t" << Name(i) << "\t" << Counter(i) << endl;
412 if (count==0) cout << "\t(none)" << endl;