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")
39 , fClassIds(AliHLTReadoutList::Class(), gkNCTPTriggerClasses)
40 , fCounters(gkNCTPTriggerClasses)
44 // see header file for class documentation
46 // refer to README to build package
48 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
51 AliHLTCTPData::AliHLTCTPData(const char* parameter)
52 : TNamed("AliHLTCTPData", "HLT counters for the CTP")
56 , fClassIds(AliHLTReadoutList::Class(), gkNCTPTriggerClasses)
57 , fCounters(gkNCTPTriggerClasses)
60 // constructor, init the CTP trigger classes
61 InitCTPTriggerClasses(parameter);
64 AliHLTCTPData::~AliHLTCTPData()
70 AliHLTCTPData::AliHLTCTPData(const AliHLTCTPData& src)
71 : TNamed(src.GetName(), src.GetTitle())
74 , fTriggers(src.fTriggers)
75 , fClassIds(src.fClassIds)
76 , fCounters(src.Counters())
83 AliHLTCTPData& AliHLTCTPData::operator=(const AliHLTCTPData& src)
85 // assignment operator, clone content
87 SetName(src.GetName());
88 SetTitle(src.GetTitle());
91 fClassIds.ExpandCreate(gkNCTPTriggerClasses);
92 for (int i=0; i<gkNCTPTriggerClasses; i++) {
93 if (i>src.fClassIds.GetLast()) break;
94 ((TNamed*)fClassIds.At(i))->SetName(src.fClassIds.At(i)->GetName());
95 ((TNamed*)fClassIds.At(i))->SetTitle(src.fClassIds.At(i)->GetTitle());
97 fCounters=src.Counters();
104 int AliHLTCTPData::Add(const AliHLTCTPData& src, int factor, int &skipped)
106 // see header file for class documentation
109 for (int i=0; i<gkNCTPTriggerClasses; i++) {
111 c=fClassIds.At(i)->GetName();
112 if (c.IsNull()) continue;
113 if (c.CompareTo(src.fClassIds.At(i)->GetName())==0) {
114 fCounters[i]+=factor*src.Counter(i);
122 AliHLTCTPData& AliHLTCTPData::operator += (const AliHLTCTPData& src)
124 // see header file for class documentation
126 int nofInconsistencies=0;
127 Add(src, 1, nofInconsistencies);
128 if (nofInconsistencies>0) {
129 HLTError("Inconsistent operants: skipping %d of %d CTP classes for operation", nofInconsistencies, gkNCTPTriggerClasses);
134 AliHLTCTPData& AliHLTCTPData::operator -= (const AliHLTCTPData& src)
136 // see header file for class documentation
138 int nofInconsistencies=0;
139 Add(src, -1, nofInconsistencies);
140 if (nofInconsistencies>0) {
141 HLTError("Inconsistent operants: skipping %d of %d CTP classes for operation", nofInconsistencies, gkNCTPTriggerClasses);
146 AliHLTCTPData AliHLTCTPData::operator + (const AliHLTCTPData& src) const
148 // see header file for class documentation
150 AliHLTCTPData result(*this);
155 AliHLTCTPData AliHLTCTPData::operator - (const AliHLTCTPData& src) const
157 // see header file for class documentation
159 AliHLTCTPData result(*this);
164 int AliHLTCTPData::InitCTPTriggerClasses(const char* ctpString)
166 // see header file for function documentation
167 if (!ctpString) return -EINVAL;
169 HLTImportant("Parameter: %s", ctpString);
173 fClassIds.ExpandCreate(gkNCTPTriggerClasses);
175 // general format of the CTP_TRIGGER_CLASS parameter
176 // <bit position>:<Trigger class identifier string>:<detector-id-nr>-<detector-id-nr>-...,<bit position>:<Trigger class identifier string>:<detector-id-nr>-<detector-id-nr>-...,...
177 HLTDebug(": %s", ctpString);
178 TString string=ctpString;
179 if (string.BeginsWith("CTP_TRIGGER_CLASS=")) string.ReplaceAll("CTP_TRIGGER_CLASS=", "");
180 TObjArray* classEntries=string.Tokenize(",");
182 enum {kBit=0, kName, kDetectors};
183 for (int i=0; i<classEntries->GetEntriesFast(); i++) {
184 TString entry=((TObjString*)classEntries->At(i))->GetString();
185 TObjArray* entryParams=entry.Tokenize(":");
187 if (entryParams->GetEntriesFast()==3 &&
188 (((TObjString*)entryParams->At(kBit))->GetString()).IsDigit()) {
189 int index=(((TObjString*)entryParams->At(kBit))->GetString()).Atoi();
190 if (index<gkNCTPTriggerClasses) {
191 AliHLTReadoutList* pCTPClass=dynamic_cast<AliHLTReadoutList*>(fClassIds.At(index));
193 fMask|=(AliHLTUInt64_t)0x1 << index;
194 pCTPClass->SetTitle("CTP Class");
195 pCTPClass->SetName((((TObjString*)entryParams->At(kName))->GetString()).Data());
196 TObjArray* detectors=(((TObjString*)entryParams->At(kDetectors))->GetString()).Tokenize("-");
198 for (int dix=0; dix<detectors->GetEntriesFast(); dix++) {
199 if (!(((TObjString*)detectors->At(dix))->GetString()).IsDigit()) {
200 HLTError("invalid detector list format: trigger class entry %s", entry.Data());
203 // see AliHLTReadoutList::EDetectorId for defines of detectors
204 pCTPClass->Enable(0x1<<(((TObjString*)detectors->At(dix))->GetString()).Atoi());
211 // the trigger bitfield is fixed to 50 bits (gkNCTPTriggerClasses)
212 HLTError("invalid trigger class entry %s, index width of trigger bitfield exceeded (%d)", entry.Data(), gkNCTPTriggerClasses);
215 HLTError("invalid trigger class entry %s", entry.Data());
229 AliHLTUInt64_t AliHLTCTPData::ActiveTriggers(const AliHLTComponentTriggerData& trigData)
231 // extract active triggers from the trigger data
233 if (trigData.fDataSize != sizeof(AliHLTEventTriggerData)) return (AliHLTUInt64_t)0;
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]&0x3ffff;
239 triggerMask|=evtData->fCommonHeader[5];
243 bool AliHLTCTPData::EvaluateCTPTriggerClass(const char* expression, const AliHLTComponentTriggerData& trigData) const
245 // see header file for function documentation
246 if (trigData.fDataSize != sizeof(AliHLTEventTriggerData)) {
247 HLTError("invalid trigger data size: %d expected %d", trigData.fDataSize, sizeof(AliHLTEventTriggerData));
251 // trigger mask is 50 bit wide and is stored in word 5 and 6 of the CDH
252 AliHLTEventTriggerData* evtData=reinterpret_cast<AliHLTEventTriggerData*>(trigData.fData);
253 AliHLTUInt64_t triggerMask=evtData->fCommonHeader[6]&0x3ffff;
255 triggerMask|=evtData->fCommonHeader[5];
257 if (fMask!=0 && (triggerMask & fMask)==0) {
258 HLTWarning("invalid trigger mask 0x%llx, unknown CTP trigger, initialized 0x%llx", triggerMask, fMask);
259 for (int i=0; i<8; i++) HLTWarning("\t CDH[%d]=0x%lx", i, evtData->fCommonHeader[i]);
263 return EvaluateCTPTriggerClass(expression, triggerMask);
266 bool AliHLTCTPData::EvaluateCTPTriggerClass(const char* expression, AliHLTUInt64_t triggerMask) const
268 // see header file for function documentation
270 // use a TFormula to interprete the expression
271 // all classname are replaced by '[n]' which means the n'th parameter in the formula
272 // the parameters are set to 0 or 1 depending on the bit in the trigger mask
273 const vector<unsigned> *pMap=&fMap;
274 vector<unsigned> tmp;
275 if (fMap.size()==0 && fClassIds.GetLast()>=0) {
276 // read map into temporary array and use it
279 static bool suppressWarning=false;
280 if (!suppressWarning) HLTWarning("map not yet initialized, creating local map (slow), suppressing further warnings");
281 suppressWarning=true;
283 vector<Double_t> par;
284 TString condition=expression;
285 for (unsigned index=0; index<pMap->size(); index++) {
286 const char* className=Name((*pMap)[index]);
287 if (className && strlen(className)>0) {
288 //HLTDebug("checking trigger class %s", className.Data());
289 if (condition.Contains(className)) {
290 TString replace; replace.Form("[%d]", par.size());
291 //HLTDebug("replacing %s with %s in \"%s\"", className.Data(), replace.Data(), condition.Data());
292 condition.ReplaceAll(className, replace);
293 if (triggerMask&((AliHLTUInt64_t)0x1<<(*pMap)[index])) par.push_back(1.0);
294 else par.push_back(0.0);
299 TFormula form("trigger expression", condition);
300 if (form.Compile()!=0) {
301 HLTError("invalid expression %s", expression);
304 if (form.EvalPar(&par[0], &par[0])>0.5) return true;
308 void AliHLTCTPData::ResetCounters()
310 // see header file for function documentation
311 fCounters.Set(gkNCTPTriggerClasses);
315 int AliHLTCTPData::Index(const char* name) const
317 // see header file for function documentation
318 TObject* obj=fClassIds.FindObject(name);
319 return obj!=NULL?fClassIds.IndexOf(obj):-1;
322 int AliHLTCTPData::CheckTrigger(const char* name) const
324 // check status of a trigger class
325 int index=Index(name);
326 if (index<0) return index;
327 return (fTriggers&(0x1<<index))>0?1:0;
330 void AliHLTCTPData::Increment(const char* classIds)
332 // see header file for function documentation
333 TString string=classIds;
334 TObjArray* classEntries=string.Tokenize(",");
336 for (int i=0; i<classEntries->GetEntriesFast(); i++) {
337 int index=Index(((TObjString*)classEntries->At(i))->GetString().Data());
338 if (index>=0 && index<fCounters.GetSize()) fCounters[index]++;
344 void AliHLTCTPData::Increment(AliHLTUInt64_t triggerPattern)
346 // see header file for function documentation
347 AliHLTUInt64_t pattern=triggerPattern&fMask;
348 for (int i=0; i<fCounters.GetSize(); i++) {
349 if ((pattern&((AliHLTUInt64_t)0x1<<i))==0) continue;
354 void AliHLTCTPData::Increment(int classIdx)
356 // see header file for function documentation
357 if (classIdx<fCounters.GetSize() &&
358 (fMask&((AliHLTUInt64_t)0x1<<classIdx))) {
359 fCounters[classIdx]++;
364 int AliHLTCTPData::Increment(AliHLTComponentTriggerData& trigData)
366 // see header file for function documentation
367 if (trigData.fDataSize != sizeof(AliHLTEventTriggerData)) {
368 HLTError("invalid trigger data size: %d expected %d", trigData.fDataSize, sizeof(AliHLTEventTriggerData));
372 // trigger mask is 50 bit wide and is stored in word 5 and 6 of the CDH
373 AliHLTEventTriggerData* evtData=reinterpret_cast<AliHLTEventTriggerData*>(trigData.fData);
374 AliHLTUInt64_t triggerMask=evtData->fCommonHeader[6]&0x3ffff;
376 triggerMask|=evtData->fCommonHeader[5];
378 if (fMask!=0 && (triggerMask & fMask)==0) {
379 HLTWarning("invalid trigger mask 0x%llx, unknown CTP trigger, initialized 0x%llx", triggerMask, fMask);
380 for (int i=0; i<8; i++) HLTWarning("\t CDH[%d]=0x%lx", i, evtData->fCommonHeader[i]);
382 Increment(triggerMask);
386 AliHLTUInt64_t AliHLTCTPData::Counter(int index) const
388 // see header file for function documentation
389 if (index>=0 && index<Counters().GetSize()) return Counters()[index];
393 AliHLTUInt64_t AliHLTCTPData::Counter(const char* classId) const
395 // see header file for function documentation
396 return Counter(Index(classId));
399 const char* AliHLTCTPData::Name(int index) const
401 // see header file for function documentation
402 if (index>fClassIds.GetLast()) return NULL;
403 return fClassIds.At(index)->GetName();
406 int AliHLTCTPData::ReadMap(vector<unsigned> &map) const
408 // read the index map for class names
409 // for nested class names (e.g. 'myclass' is contained in
410 // 'myclassA') the longer names is added first to the map.
411 for (int index=0; index<=fClassIds.GetLast(); index++) {
412 vector<unsigned>::iterator element=map.begin();
413 for (; element!=map.end(); element++) {
414 TString name=Name(index);
415 if (name.Contains(Name(*element))) {
416 // current name contains another one already in the map
417 // -> add before and go to next entry
418 element=map.insert(element, index);
423 if (element==map.end()) {
424 // unique class name, append to map
425 map.push_back(index);
432 AliHLTEventDDL AliHLTCTPData::ReadoutList(const AliHLTComponentTriggerData& trigData) const
434 // see header file for function documentation
435 if (trigData.fDataSize != sizeof(AliHLTEventTriggerData)) {
436 HLTError("invalid trigger data size: %d expected %d", trigData.fDataSize, sizeof(AliHLTEventTriggerData));
437 AliHLTEventDDL dummy;
438 memset(&dummy, 0, sizeof(AliHLTEventDDL));
442 // trigger mask is 50 bit wide and is stored in word 5 and 6 of the CDH
443 AliHLTEventTriggerData* evtData=reinterpret_cast<AliHLTEventTriggerData*>(trigData.fData);
444 AliHLTUInt64_t triggerMask=evtData->fCommonHeader[6]&0x3ffff;
446 triggerMask|=evtData->fCommonHeader[5];
448 if (fMask!=0 && (triggerMask & fMask)==0) {
449 HLTWarning("invalid trigger mask 0x%llx, unknown CTP trigger, initialized 0x%llx", triggerMask, fMask);
450 for (int i=0; i<8; i++) HLTWarning("\t CDH[%d]=0x%lx", i, evtData->fCommonHeader[i]);
453 return ReadoutList(triggerMask);
456 AliHLTEventDDL AliHLTCTPData::ReadoutList(AliHLTUInt64_t triggerMask) const
458 // take an 'OR' of all active trigger classes
459 AliHLTReadoutList list;
460 for (int i=0; i<gkNCTPTriggerClasses; i++) {
461 if (i>fClassIds.GetLast()) break;
462 if ((triggerMask&((AliHLTUInt64_t)0x1<<i))==0) continue;
463 AliHLTReadoutList* tcrl=(AliHLTReadoutList*)fClassIds.At(i);
471 void AliHLTCTPData::Print(Option_t* /*option*/) const
473 // see header file for function documentation
474 cout << GetTitle() << endl;
475 cout << "\tactive trigger mask: 0x" << hex << fTriggers << dec << endl;
477 for (int i=0; i<gkNCTPTriggerClasses; i++) {
478 if (i>=Counters().GetSize()) break;
479 if (i>fClassIds.GetLast()) break;
480 if ((fMask&((AliHLTUInt64_t)0x1<<i))==0) continue;
482 cout << "\t" << i << "\t" << Name(i) << "\t" << Counter(i) << endl;
484 if (count==0) cout << "\t(none)" << endl;