--- /dev/null
+// $Id$
+
+//**************************************************************************
+//* This file is property of and copyright by the ALICE HLT Project *
+//* ALICE Experiment at CERN, All rights reserved. *
+//* *
+//* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
+//* Timm Steinbeck <timm@kip.uni-heidelberg.de> *
+//* for The ALICE HLT Project. *
+//* *
+//* Permission to use, copy, modify and distribute this software and its *
+//* documentation strictly for non-commercial purposes is hereby granted *
+//* without fee, provided that the above copyright notice appears in all *
+//* copies and that both the copyright notice and this permission notice *
+//* appear in the supporting documentation. The authors make no claims *
+//* about the suitability of this software for any purpose. It is *
+//* provided "as is" without express or implied warranty. *
+//**************************************************************************
+
+/** @file AliHLTCTPData.cxx
+ @author Matthias Richter
+ @date 2009-08-20
+ @brief Container for CTP trigger classes and counters
+*/
+
+#include "AliHLTCTPData.h"
+#include "TClass.h"
+#include "TNamed.h"
+#include "TObjString.h"
+#include "TFormula.h"
+
+/** ROOT macro for the implementation of ROOT specific class methods */
+ClassImp(AliHLTCTPData)
+
+AliHLTCTPData::AliHLTCTPData()
+: TNamed("AliHLTCTPData", "HLT counters for the CTP")
+ , AliHLTLogging()
+ , fMask(0)
+ , fClassIds(TNamed::Class(), gkNCTPTriggerClasses)
+ , fCounters()
+{
+ // see header file for class documentation
+ // or
+ // refer to README to build package
+ // or
+ // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
+}
+
+AliHLTCTPData::AliHLTCTPData(const char* parameter)
+ : TNamed("AliHLTCTPData", "HLT counters for the CTP")
+ , AliHLTLogging()
+ , fMask(0)
+ , fClassIds(TNamed::Class(), gkNCTPTriggerClasses)
+ , fCounters()
+{
+ // see header file for class documentation
+ InitCTPTriggerClasses(parameter);
+}
+
+AliHLTCTPData::~AliHLTCTPData()
+{
+ // see header file for class documentation
+ fClassIds.Delete();
+}
+
+int AliHLTCTPData::InitCTPTriggerClasses(const char* ctpString)
+{
+ // see header file for function documentation
+ if (!ctpString) return -EINVAL;
+
+ fMask=0;
+ fClassIds.Delete();
+ fClassIds.ExpandCreate(gkNCTPTriggerClasses);
+
+ // general format of the CTP_TRIGGER_CLASS parameter
+ // <bit position>:<Trigger class identifier string>:<detector-id-nr>-<detector-id-nr>-...,<bit position>:<Trigger class identifier string>:<detector-id-nr>-<detector-id-nr>-...,...
+ // the detector ids are ignored for the moment
+ HLTDebug(": %s", ctpString);
+ TString string=ctpString;
+ TObjArray* classEntries=string.Tokenize(",");
+ if (classEntries) {
+ for (int i=0; i<classEntries->GetEntries(); i++) {
+ TString entry=((TObjString*)classEntries->At(i))->GetString();
+ TObjArray* entryParams=entry.Tokenize(":");
+ if (entryParams) {
+ if (entryParams->GetEntries()==3 &&
+ (((TObjString*)entryParams->At(0))->GetString()).IsDigit()) {
+ int index=(((TObjString*)entryParams->At(0))->GetString()).Atoi();
+ if (index<gkNCTPTriggerClasses) {
+ fMask|=(AliHLTUInt64_t)0x1 << index;
+ ((TNamed*)fClassIds.At(index))->SetTitle("TriggerClass");
+ ((TNamed*)fClassIds.At(index))->SetName((((TObjString*)entryParams->At(1))->GetString()).Data());
+ } else {
+ // the trigger bitfield is fixed to 50 bits (gkNCTPTriggerClasses)
+ HLTError("invalid trigger class entry %s, index width of trigger bitfield", entry.Data());
+ }
+ } else {
+ HLTError("invalid trigger class entry %s", entry.Data());
+ }
+ delete entryParams;
+ }
+ }
+ delete classEntries;
+ }
+
+ ResetCounters();
+
+ return 0;
+}
+
+bool AliHLTCTPData::EvaluateCTPTriggerClass(const char* expression, AliHLTComponentTriggerData& trigData) const
+{
+ // see header file for function documentation
+ if (trigData.fDataSize != sizeof(AliHLTEventTriggerData)) {
+ HLTError("invalid trigger data size: %d expected %d", trigData.fDataSize, sizeof(AliHLTEventTriggerData));
+ return false;
+ }
+
+ // trigger mask is 50 bit wide and is stored in word 5 and 6 of the CDH
+ AliHLTEventTriggerData* evtData=reinterpret_cast<AliHLTEventTriggerData*>(trigData.fData);
+ AliHLTUInt64_t triggerMask=evtData->fCommonHeader[6];
+ triggerMask<<=32;
+ triggerMask|=evtData->fCommonHeader[5];
+
+ if (fMask!=0 && (triggerMask & fMask)==0) {
+ HLTWarning("invalid trigger mask 0x%llx, unknown CTP trigger", triggerMask);
+ return false;
+ }
+
+ // use a TFormula to interprete the expression
+ // all classname are replaced by '[n]' which means the n'th parameter in the formula
+ // the parameters are set to 0 or 1 depending on the bit in the trigger mask
+ //
+ // TODO: this will most likely fail for class names like 'base', 'baseA', 'baseB'
+ // the class names must be fully unique, none must be contained as substring in
+ // another class name. Probably not needed for the moment but needs to be extended.
+ vector<Double_t> par;
+ TString condition=expression;
+ for (int i=0; i<gkNCTPTriggerClasses; i++) {
+ const char* className=Name(i);
+ if (className && strlen(className)>0) {
+ //HLTDebug("checking trigger class %s", className.Data());
+ if (condition.Contains(className)) {
+ TString replace; replace.Form("[%d]", par.size());
+ //HLTDebug("replacing %s with %s in \"%s\"", className.Data(), replace.Data(), condition.Data());
+ condition.ReplaceAll(className, replace);
+ if (triggerMask&((AliHLTUInt64_t)0x1<<i)) par.push_back(1.0);
+ else par.push_back(0.0);
+ }
+ }
+ }
+
+ TFormula form("trigger expression", condition);
+ if (form.Compile()!=0) {
+ HLTError("invalid expression %s", expression);
+ return false;
+ }
+ if (form.EvalPar(&par[0], &par[0])>0.5) return true;
+ return false;
+}
+
+void AliHLTCTPData::ResetCounters()
+{
+ // see header file for function documentation
+ fCounters.Set(gkNCTPTriggerClasses);
+ fCounters.Reset();
+}
+
+int AliHLTCTPData::Index(const char* name) const
+{
+ // see header file for function documentation
+ TObject* obj=fClassIds.FindObject(name);
+ return obj!=NULL?fClassIds.IndexOf(obj):-1;
+}
+
+void AliHLTCTPData::Increment(const char* classIds)
+{
+ // see header file for function documentation
+ TString string=classIds;
+ TObjArray* classEntries=string.Tokenize(",");
+ if (classEntries) {
+ for (int i=0; i<classEntries->GetEntries(); i++) {
+ int index=Index(((TObjString*)classEntries->At(i))->GetString().Data());
+ if (index>=0 && index<fCounters.GetSize()) fCounters[index]++;
+ }
+ delete classEntries;
+ }
+}
+
+void AliHLTCTPData::Increment(AliHLTUInt64_t triggerPattern)
+{
+ // see header file for function documentation
+ AliHLTUInt64_t pattern=triggerPattern&fMask;
+ for (int i=0; i<fCounters.GetSize(); i++) {
+ if ((pattern&((AliHLTUInt64_t)0x1<<i))==0) continue;
+ fCounters[i]++;
+ }
+}
+
+void AliHLTCTPData::Increment(int classIdx)
+{
+ // see header file for function documentation
+ if (classIdx<fCounters.GetSize() &&
+ (fMask&((AliHLTUInt64_t)0x1<<classIdx))) {
+ fCounters[classIdx]++;
+ }
+
+}
+
+int AliHLTCTPData::Increment(AliHLTComponentTriggerData& trigData)
+{
+ // see header file for function documentation
+ if (trigData.fDataSize != sizeof(AliHLTEventTriggerData)) {
+ HLTError("invalid trigger data size: %d expected %d", trigData.fDataSize, sizeof(AliHLTEventTriggerData));
+ return -EBADF;
+ }
+
+ // trigger mask is 50 bit wide and is stored in word 5 and 6 of the CDH
+ AliHLTEventTriggerData* evtData=reinterpret_cast<AliHLTEventTriggerData*>(trigData.fData);
+ AliHLTUInt64_t triggerMask=evtData->fCommonHeader[6];
+ triggerMask<<=32;
+ triggerMask|=evtData->fCommonHeader[5];
+
+ if (fMask!=0 && (triggerMask & fMask)==0) {
+ HLTWarning("invalid trigger mask 0x%llx, unknown CTP trigger, initialized 0x%llx", triggerMask, fMask);
+ }
+ Increment(triggerMask);
+ return 0;
+}
+
+AliHLTUInt64_t AliHLTCTPData::Counter(int index) const
+{
+ // see header file for function documentation
+ if (index>=0 && index<Counters().GetSize()) return Counters()[index];
+ return 0;
+}
+
+AliHLTUInt64_t AliHLTCTPData::Counter(const char* classId) const
+{
+ // see header file for function documentation
+ return Counter(Index(classId));
+}
+
+const char* AliHLTCTPData::Name(int index) const
+{
+ // see header file for function documentation
+ if (index>fClassIds.GetLast()) return NULL;
+ return fClassIds.At(index)->GetName();
+}
+
+void AliHLTCTPData::Print(Option_t* /*option*/) const
+{
+ // see header file for function documentation
+ cout << "CTP counters:" << endl;
+ int count=0;
+ for (int i=0; i<gkNCTPTriggerClasses; i++) {
+ if (i>=Counters().GetSize()) break;
+ if (i>fClassIds.GetLast()) break;
+ if ((fMask&((AliHLTUInt64_t)0x1<<i))==0) continue;
+ count++;
+ cout << "\t" << i << "\t" << Name(i) << "\t" << Counter(i) << endl;
+ }
+ if (count==0) cout << "\t(none)" << endl;
+}
--- /dev/null
+//-*- Mode: C++ -*-
+// $Id$
+
+#ifndef ALIHLTCTPDATA_H
+#define ALIHLTCTPDATA_H
+//* This file is property of and copyright by the ALICE HLT Project *
+//* ALICE Experiment at CERN, All rights reserved. *
+//* See cxx source for full Copyright notice *
+
+/** @file AliHLTCTPData.h
+ @author Matthias Richter
+ @date 2009-08-20
+ @brief Container for CTP trigger classes and counters
+*/
+
+#include "TNamed.h"
+#include "TClonesArray.h"
+#include "TArrayL64.h"
+#include "AliHLTLogging.h"
+#include "AliHLTDataTypes.h"
+
+/**
+ * @class AliHLTCTPData
+ * This is a container for the CTP trigger classes, the mapping to the bit
+ * field, and counters.
+ *
+ * The object is also stored as part of the HLTGlobalTriggerDecision
+ * @ingroup alihlt_trigger
+ */
+class AliHLTCTPData: public TNamed, public AliHLTLogging
+{
+ public:
+ /// default constructor
+ AliHLTCTPData();
+ /// standard constructor including initialization from CTP_TRIGGER_CLASS
+ AliHLTCTPData(const char* parameter);
+ /// destructor
+ virtual ~AliHLTCTPData();
+
+ /**
+ * Init the class ids and mapping from the CTP_TRIGGER_CLASS parameter.
+ * The general format of the parameter is as follows:
+ */
+ int InitCTPTriggerClasses(const char* ctpString);
+
+ /**
+ * Evaluate an expression of trigger class ids with respect to the trigger mask.
+ */
+ bool EvaluateCTPTriggerClass(const char* expression, AliHLTComponentTriggerData& trigData) const;
+
+ /**
+ * Reset all counters
+ */
+ void ResetCounters();
+
+ /**
+ * Get index of a trigger class in the tigger pattern
+ */
+ int Index(const char* name) const;
+
+ /**
+ * Increment counter for CTP trigger classes
+ * @param classIds comma separated list of class ids
+ */
+ void Increment(const char* classIds);
+
+ /**
+ * Increment counter for CTP trigger classes
+ * @param triggerPattern corresponds to the 50bit trigger mask in the CDH
+ */
+ void Increment(AliHLTUInt64_t triggerPattern);
+
+ /**
+ * Increment counter for a CTP trigger class
+ * @param classIdx index of the class in the 50bit trigger mask
+ */
+ void Increment(int classIdx);
+
+ /**
+ * Increment counters according to the trigger data struct.
+ * First extract trigger pattern from the CDH and then
+ * increment from the trigger pattern.
+ */
+ int Increment(AliHLTComponentTriggerData& trigData);
+
+ /**
+ * Inherited from TObject, this prints the contents of the trigger decision.
+ */
+ virtual void Print(Option_t* option = "") const;
+
+ AliHLTUInt64_t Mask() const { return fMask; }
+ const TArrayL64& Counters() const { return fCounters; }
+ AliHLTUInt64_t Counter(int index) const;
+ AliHLTUInt64_t Counter(const char* classId) const;
+ const char* Name(int index) const;
+
+ protected:
+ private:
+ /// copy constructor prohibited
+ AliHLTCTPData(const AliHLTCTPData&);
+ ///assignment operator prohibited
+ AliHLTCTPData& operator=(const AliHLTCTPData&);
+
+ AliHLTUInt64_t fMask; /// mask of initialized trigger classes
+ TClonesArray fClassIds; /// array of trigger class ids
+ TArrayL64 fCounters; /// trigger class counters
+
+ ClassDef(AliHLTCTPData, 0)
+};
+
+#endif