Bug fix: AliHLTTPCRawSpacePointContainer
[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> *
1dbbd625 8//* for The ALICE HLT Project. *
9//* *
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//**************************************************************************
18
ffda78e3 19// @file AliHLTCTPData.cxx
20// @author Matthias Richter
21// @date 2009-08-20
22// @brief Container for CTP trigger classes and counters
23// @note
1dbbd625 24
25#include "AliHLTCTPData.h"
26#include "TClass.h"
1dbbd625 27#include "TObjString.h"
28#include "TFormula.h"
89413559 29#include "AliHLTComponent.h"
30#include "AliRawDataHeader.h"
1dbbd625 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)
edd72347 39 , fTriggers(0)
1462df14 40 , fClassIds(AliHLTReadoutList::Class(), gkNCTPTriggerClasses)
59be6254 41 , fCounters(gkNCTPTriggerClasses)
ffda78e3 42 , fMap()
1dbbd625 43{
ffda78e3 44 // constructor
1dbbd625 45 // see header file for class documentation
46 // or
47 // refer to README to build package
48 // or
49 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
50}
51
52AliHLTCTPData::AliHLTCTPData(const char* parameter)
53 : TNamed("AliHLTCTPData", "HLT counters for the CTP")
54 , AliHLTLogging()
55 , fMask(0)
edd72347 56 , fTriggers(0)
1462df14 57 , fClassIds(AliHLTReadoutList::Class(), gkNCTPTriggerClasses)
59be6254 58 , fCounters(gkNCTPTriggerClasses)
ffda78e3 59 , fMap()
1dbbd625 60{
ffda78e3 61 // constructor, init the CTP trigger classes
1dbbd625 62 InitCTPTriggerClasses(parameter);
63}
64
65AliHLTCTPData::~AliHLTCTPData()
66{
ffda78e3 67 // destructor
1dbbd625 68 fClassIds.Delete();
69}
70
59be6254 71AliHLTCTPData::AliHLTCTPData(const AliHLTCTPData& src)
72 : TNamed(src.GetName(), src.GetTitle())
73 , AliHLTLogging()
74 , fMask(src.Mask())
edd72347 75 , fTriggers(src.fTriggers)
59be6254 76 , fClassIds(src.fClassIds)
77 , fCounters(src.Counters())
ffda78e3 78 , fMap()
59be6254 79{
ffda78e3 80 // copy constructor
81 ReadMap();
59be6254 82}
83
84AliHLTCTPData& AliHLTCTPData::operator=(const AliHLTCTPData& src)
85{
ffda78e3 86 // assignment operator, clone content
59be6254 87 if (this!=&src) {
88 SetName(src.GetName());
89 SetTitle(src.GetTitle());
90 fMask=src.Mask();
91 fClassIds.Delete();
92 fClassIds.ExpandCreate(gkNCTPTriggerClasses);
93 for (int i=0; i<gkNCTPTriggerClasses; i++) {
4a4318fe 94 if (i>src.fClassIds.GetLast()) break;
59be6254 95 ((TNamed*)fClassIds.At(i))->SetName(src.fClassIds.At(i)->GetName());
96 ((TNamed*)fClassIds.At(i))->SetTitle(src.fClassIds.At(i)->GetTitle());
97 }
98 fCounters=src.Counters();
99 }
100
ffda78e3 101 ReadMap();
59be6254 102 return *this;
103}
104
105int AliHLTCTPData::Add(const AliHLTCTPData& src, int factor, int &skipped)
106{
107 // see header file for class documentation
108
109 skipped=0;
110 for (int i=0; i<gkNCTPTriggerClasses; i++) {
111 TString c;
112 c=fClassIds.At(i)->GetName();
113 if (c.IsNull()) continue;
114 if (c.CompareTo(src.fClassIds.At(i)->GetName())==0) {
115 fCounters[i]+=factor*src.Counter(i);
116 } else {
117 skipped++;
118 }
119 }
120 return 0;
121}
122
123AliHLTCTPData& AliHLTCTPData::operator += (const AliHLTCTPData& src)
124{
125 // see header file for class documentation
126
127 int nofInconsistencies=0;
128 Add(src, 1, nofInconsistencies);
129 if (nofInconsistencies>0) {
130 HLTError("Inconsistent operants: skipping %d of %d CTP classes for operation", nofInconsistencies, gkNCTPTriggerClasses);
131 }
132 return *this;
133}
134
135AliHLTCTPData& AliHLTCTPData::operator -= (const AliHLTCTPData& src)
136{
137 // see header file for class documentation
138
139 int nofInconsistencies=0;
140 Add(src, -1, nofInconsistencies);
141 if (nofInconsistencies>0) {
142 HLTError("Inconsistent operants: skipping %d of %d CTP classes for operation", nofInconsistencies, gkNCTPTriggerClasses);
143 }
144 return *this;
145}
146
147AliHLTCTPData AliHLTCTPData::operator + (const AliHLTCTPData& src) const
148{
149 // see header file for class documentation
150
151 AliHLTCTPData result(*this);
152 result+=src;
153 return result;
154}
155
156AliHLTCTPData AliHLTCTPData::operator - (const AliHLTCTPData& src) const
157{
158 // see header file for class documentation
159
160 AliHLTCTPData result(*this);
161 result-=src;
162 return result;
163}
164
1dbbd625 165int AliHLTCTPData::InitCTPTriggerClasses(const char* ctpString)
166{
167 // see header file for function documentation
168 if (!ctpString) return -EINVAL;
169
5be104b8 170 HLTImportant("Parameter: %s", ctpString);
171
1dbbd625 172 fMask=0;
173 fClassIds.Delete();
174 fClassIds.ExpandCreate(gkNCTPTriggerClasses);
175
176 // general format of the CTP_TRIGGER_CLASS parameter
177 // <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 178 HLTDebug(": %s", ctpString);
179 TString string=ctpString;
1462df14 180 if (string.BeginsWith("CTP_TRIGGER_CLASS=")) string.ReplaceAll("CTP_TRIGGER_CLASS=", "");
1dbbd625 181 TObjArray* classEntries=string.Tokenize(",");
182 if (classEntries) {
1462df14 183 enum {kBit=0, kName, kDetectors};
77fd699f 184 for (int i=0; i<classEntries->GetEntriesFast(); i++) {
1dbbd625 185 TString entry=((TObjString*)classEntries->At(i))->GetString();
186 TObjArray* entryParams=entry.Tokenize(":");
187 if (entryParams) {
77fd699f 188 if (entryParams->GetEntriesFast()==3 &&
1462df14 189 (((TObjString*)entryParams->At(kBit))->GetString()).IsDigit()) {
190 int index=(((TObjString*)entryParams->At(kBit))->GetString()).Atoi();
1dbbd625 191 if (index<gkNCTPTriggerClasses) {
1462df14 192 AliHLTReadoutList* pCTPClass=dynamic_cast<AliHLTReadoutList*>(fClassIds.At(index));
193 if (pCTPClass) {
194 fMask|=(AliHLTUInt64_t)0x1 << index;
195 pCTPClass->SetTitle("CTP Class");
196 pCTPClass->SetName((((TObjString*)entryParams->At(kName))->GetString()).Data());
197 TObjArray* detectors=(((TObjString*)entryParams->At(kDetectors))->GetString()).Tokenize("-");
198 if (detectors) {
199 for (int dix=0; dix<detectors->GetEntriesFast(); dix++) {
200 if (!(((TObjString*)detectors->At(dix))->GetString()).IsDigit()) {
201 HLTError("invalid detector list format: trigger class entry %s", entry.Data());
202 break;
203 }
204 // see AliHLTReadoutList::EDetectorId for defines of detectors
205 pCTPClass->Enable(0x1<<(((TObjString*)detectors->At(dix))->GetString()).Atoi());
206 }
207 delete detectors;
208 }
209 } else {
210 }
1dbbd625 211 } else {
212 // the trigger bitfield is fixed to 50 bits (gkNCTPTriggerClasses)
1462df14 213 HLTError("invalid trigger class entry %s, index width of trigger bitfield exceeded (%d)", entry.Data(), gkNCTPTriggerClasses);
1dbbd625 214 }
215 } else {
216 HLTError("invalid trigger class entry %s", entry.Data());
217 }
218 delete entryParams;
219 }
220 }
221 delete classEntries;
222 }
223
224 ResetCounters();
ffda78e3 225 ReadMap();
1dbbd625 226
227 return 0;
228}
229
e5339167 230AliHLTUInt64_t AliHLTCTPData::ActiveTriggers(const AliHLTComponentTriggerData& trigData)
231{
232 // extract active triggers from the trigger data
e5339167 233
89413559 234 const AliRawDataHeader* cdh = NULL;
235 if (AliHLTComponent::ExtractTriggerData(trigData, NULL, NULL, &cdh, NULL) != 0) return (AliHLTUInt64_t)0;
9e14734f 236 if ((cdh->GetL1TriggerMessage() & 0x1) == 0x1) return 0x0; // invalid for software triggers.
e5339167 237 // trigger mask is 50 bit wide and is stored in word 5 and 6 of the CDH
89413559 238 AliHLTUInt64_t triggerMask = cdh->GetTriggerClasses();
e5339167 239 return triggerMask;
240}
241
edd72347 242bool AliHLTCTPData::EvaluateCTPTriggerClass(const char* expression, const AliHLTComponentTriggerData& trigData) const
1dbbd625 243{
244 // see header file for function documentation
89413559 245
246 const AliRawDataHeader* cdh = NULL;
247 if (AliHLTComponent::ExtractTriggerData(trigData, NULL, NULL, &cdh, NULL, true) != 0) return false;
9e14734f 248 if ((cdh->GetL1TriggerMessage() & 0x1) == 0x1) return false; // invalid for software triggers.
1dbbd625 249 // trigger mask is 50 bit wide and is stored in word 5 and 6 of the CDH
89413559 250 AliHLTUInt64_t triggerMask = cdh->GetTriggerClasses();
1dbbd625 251
252 if (fMask!=0 && (triggerMask & fMask)==0) {
89413559 253 AliHLTEventTriggerData* evtData=reinterpret_cast<AliHLTEventTriggerData*>(trigData.fData);
5be104b8 254 HLTWarning("invalid trigger mask 0x%llx, unknown CTP trigger, initialized 0x%llx", triggerMask, fMask);
255 for (int i=0; i<8; i++) HLTWarning("\t CDH[%d]=0x%lx", i, evtData->fCommonHeader[i]);
1dbbd625 256 return false;
257 }
258
edd72347 259 return EvaluateCTPTriggerClass(expression, triggerMask);
260}
261
262bool AliHLTCTPData::EvaluateCTPTriggerClass(const char* expression, AliHLTUInt64_t triggerMask) const
263{
264 // see header file for function documentation
265
1dbbd625 266 // use a TFormula to interprete the expression
267 // all classname are replaced by '[n]' which means the n'th parameter in the formula
268 // the parameters are set to 0 or 1 depending on the bit in the trigger mask
ffda78e3 269 const vector<unsigned> *pMap=&fMap;
270 vector<unsigned> tmp;
271 if (fMap.size()==0 && fClassIds.GetLast()>=0) {
272 // read map into temporary array and use it
273 ReadMap(tmp);
274 pMap=&tmp;
275 static bool suppressWarning=false;
276 if (!suppressWarning) HLTWarning("map not yet initialized, creating local map (slow), suppressing further warnings");
277 suppressWarning=true;
278 }
1dbbd625 279 vector<Double_t> par;
280 TString condition=expression;
ffda78e3 281 for (unsigned index=0; index<pMap->size(); index++) {
282 const char* className=Name((*pMap)[index]);
1dbbd625 283 if (className && strlen(className)>0) {
284 //HLTDebug("checking trigger class %s", className.Data());
285 if (condition.Contains(className)) {
9678969f 286 TString replace; replace.Form("[%d]", (int)par.size());
1dbbd625 287 //HLTDebug("replacing %s with %s in \"%s\"", className.Data(), replace.Data(), condition.Data());
288 condition.ReplaceAll(className, replace);
ffda78e3 289 if (triggerMask&((AliHLTUInt64_t)0x1<<(*pMap)[index])) par.push_back(1.0);
1dbbd625 290 else par.push_back(0.0);
291 }
292 }
293 }
294
295 TFormula form("trigger expression", condition);
296 if (form.Compile()!=0) {
297 HLTError("invalid expression %s", expression);
298 return false;
299 }
300 if (form.EvalPar(&par[0], &par[0])>0.5) return true;
301 return false;
302}
303
304void AliHLTCTPData::ResetCounters()
305{
306 // see header file for function documentation
307 fCounters.Set(gkNCTPTriggerClasses);
308 fCounters.Reset();
309}
310
311int AliHLTCTPData::Index(const char* name) const
312{
313 // see header file for function documentation
314 TObject* obj=fClassIds.FindObject(name);
315 return obj!=NULL?fClassIds.IndexOf(obj):-1;
316}
317
ffda78e3 318int AliHLTCTPData::CheckTrigger(const char* name) const
319{
320 // check status of a trigger class
321 int index=Index(name);
322 if (index<0) return index;
323 return (fTriggers&(0x1<<index))>0?1:0;
324}
325
1dbbd625 326void AliHLTCTPData::Increment(const char* classIds)
327{
328 // see header file for function documentation
329 TString string=classIds;
330 TObjArray* classEntries=string.Tokenize(",");
331 if (classEntries) {
77fd699f 332 for (int i=0; i<classEntries->GetEntriesFast(); i++) {
1dbbd625 333 int index=Index(((TObjString*)classEntries->At(i))->GetString().Data());
334 if (index>=0 && index<fCounters.GetSize()) fCounters[index]++;
335 }
336 delete classEntries;
337 }
338}
339
340void AliHLTCTPData::Increment(AliHLTUInt64_t triggerPattern)
341{
342 // see header file for function documentation
343 AliHLTUInt64_t pattern=triggerPattern&fMask;
344 for (int i=0; i<fCounters.GetSize(); i++) {
345 if ((pattern&((AliHLTUInt64_t)0x1<<i))==0) continue;
346 fCounters[i]++;
347 }
348}
349
350void AliHLTCTPData::Increment(int classIdx)
351{
352 // see header file for function documentation
353 if (classIdx<fCounters.GetSize() &&
354 (fMask&((AliHLTUInt64_t)0x1<<classIdx))) {
355 fCounters[classIdx]++;
356 }
357
358}
359
360int AliHLTCTPData::Increment(AliHLTComponentTriggerData& trigData)
361{
362 // see header file for function documentation
89413559 363 const AliRawDataHeader* cdh = NULL;
364 int result = AliHLTComponent::ExtractTriggerData(trigData, NULL, NULL, &cdh, NULL, true);
365 if (result != 0) return result;
9e14734f 366 if ((cdh->GetL1TriggerMessage() & 0x1) == 0x1) return 0; // invalid for software triggers.
1dbbd625 367 // trigger mask is 50 bit wide and is stored in word 5 and 6 of the CDH
89413559 368 AliHLTUInt64_t triggerMask = cdh->GetTriggerClasses();
1dbbd625 369
370 if (fMask!=0 && (triggerMask & fMask)==0) {
89413559 371 AliHLTEventTriggerData* evtData=reinterpret_cast<AliHLTEventTriggerData*>(trigData.fData);
1dbbd625 372 HLTWarning("invalid trigger mask 0x%llx, unknown CTP trigger, initialized 0x%llx", triggerMask, fMask);
5be104b8 373 for (int i=0; i<8; i++) HLTWarning("\t CDH[%d]=0x%lx", i, evtData->fCommonHeader[i]);
1dbbd625 374 }
375 Increment(triggerMask);
376 return 0;
377}
378
379AliHLTUInt64_t AliHLTCTPData::Counter(int index) const
380{
381 // see header file for function documentation
382 if (index>=0 && index<Counters().GetSize()) return Counters()[index];
383 return 0;
384}
385
386AliHLTUInt64_t AliHLTCTPData::Counter(const char* classId) const
387{
388 // see header file for function documentation
389 return Counter(Index(classId));
390}
391
392const char* AliHLTCTPData::Name(int index) const
393{
394 // see header file for function documentation
395 if (index>fClassIds.GetLast()) return NULL;
396 return fClassIds.At(index)->GetName();
397}
398
ffda78e3 399int AliHLTCTPData::ReadMap(vector<unsigned> &map) const
400{
401 // read the index map for class names
402 // for nested class names (e.g. 'myclass' is contained in
403 // 'myclassA') the longer names is added first to the map.
404 for (int index=0; index<=fClassIds.GetLast(); index++) {
405 vector<unsigned>::iterator element=map.begin();
406 for (; element!=map.end(); element++) {
407 TString name=Name(index);
408 if (name.Contains(Name(*element))) {
409 // current name contains another one already in the map
410 // -> add before and go to next entry
411 element=map.insert(element, index);
412 break;
413 }
414 }
415
416 if (element==map.end()) {
417 // unique class name, append to map
418 map.push_back(index);
419 }
420 }
421 return 0;
422}
423
424
89413559 425AliHLTReadoutList AliHLTCTPData::ReadoutList(const AliHLTComponentTriggerData& trigData) const
1462df14 426{
427 // see header file for function documentation
1462df14 428
89413559 429 const AliRawDataHeader* cdh = NULL;
430 if (AliHLTComponent::ExtractTriggerData(trigData, NULL, NULL, &cdh, NULL, true) != 0) return AliHLTReadoutList();
ad1d7043 431 // Check if we are dealing with a software trigger. If so then we need to return
432 // a readout list with everything set because the CTP trigger bits are invalid.
433 // Thus we assume that everything should be read out.
434 if ((cdh->GetL1TriggerMessage() & 0x1) == 0x1) return ~ AliHLTReadoutList();
1462df14 435 // trigger mask is 50 bit wide and is stored in word 5 and 6 of the CDH
89413559 436 AliHLTUInt64_t triggerMask = cdh->GetTriggerClasses();
1462df14 437
5be104b8 438 if (fMask!=0 && (triggerMask & fMask)==0) {
89413559 439 AliHLTEventTriggerData* evtData=reinterpret_cast<AliHLTEventTriggerData*>(trigData.fData);
5be104b8 440 HLTWarning("invalid trigger mask 0x%llx, unknown CTP trigger, initialized 0x%llx", triggerMask, fMask);
441 for (int i=0; i<8; i++) HLTWarning("\t CDH[%d]=0x%lx", i, evtData->fCommonHeader[i]);
442 }
443
f11febe7 444 return ReadoutList(triggerMask);
445}
446
89413559 447AliHLTReadoutList AliHLTCTPData::ReadoutList(AliHLTUInt64_t triggerMask) const
f11febe7 448{
1462df14 449 // take an 'OR' of all active trigger classes
450 AliHLTReadoutList list;
451 for (int i=0; i<gkNCTPTriggerClasses; i++) {
452 if (i>fClassIds.GetLast()) break;
453 if ((triggerMask&((AliHLTUInt64_t)0x1<<i))==0) continue;
5be104b8 454 AliHLTReadoutList* tcrl=(AliHLTReadoutList*)fClassIds.At(i);
45398383 455 list.OrEq(*tcrl);
1462df14 456 }
457
458 return list;
459}
460
f11febe7 461
1dbbd625 462void AliHLTCTPData::Print(Option_t* /*option*/) const
463{
464 // see header file for function documentation
59be6254 465 cout << GetTitle() << endl;
edd72347 466 cout << "\tactive trigger mask: 0x" << hex << fTriggers << dec << endl;
1dbbd625 467 int count=0;
468 for (int i=0; i<gkNCTPTriggerClasses; i++) {
469 if (i>=Counters().GetSize()) break;
470 if (i>fClassIds.GetLast()) break;
471 if ((fMask&((AliHLTUInt64_t)0x1<<i))==0) continue;
472 count++;
473 cout << "\t" << i << "\t" << Name(i) << "\t" << Counter(i) << endl;
474 }
475 if (count==0) cout << "\t(none)" << endl;
476}