adding a member for the active CTP trigger mask to the CTP data object and setting...
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTCTPData.cxx
index 6cc17a857679771dd28700fe3c3b140295d467a7..4d5b7ea05f414fb4ce0ac6a219eaa6ed6476a13e 100644 (file)
@@ -5,7 +5,6 @@
 //* 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   *
@@ -24,8 +23,8 @@
 */
 
 #include "AliHLTCTPData.h"
+#include "AliHLTReadoutList.h"
 #include "TClass.h"
-#include "TNamed.h"
 #include "TObjString.h"
 #include "TFormula.h"
 
 ClassImp(AliHLTCTPData)
 
 AliHLTCTPData::AliHLTCTPData()
-: TNamed("AliHLTCTPData", "HLT counters for the CTP")
+  : TNamed("AliHLTCTPData", "HLT counters for the CTP")
   , AliHLTLogging()
   , fMask(0)
-  , fClassIds(TNamed::Class(), gkNCTPTriggerClasses)
-  , fCounters()
+  , fTriggers(0)
+  , fClassIds(AliHLTReadoutList::Class(), gkNCTPTriggerClasses)
+  , fCounters(gkNCTPTriggerClasses)
 {
   // see header file for class documentation
   // or
@@ -50,8 +50,9 @@ AliHLTCTPData::AliHLTCTPData(const char* parameter)
   : TNamed("AliHLTCTPData", "HLT counters for the CTP")
   , AliHLTLogging()
   , fMask(0)
-  , fClassIds(TNamed::Class(), gkNCTPTriggerClasses)
-  , fCounters()
+  , fTriggers(0)
+  , fClassIds(AliHLTReadoutList::Class(), gkNCTPTriggerClasses)
+  , fCounters(gkNCTPTriggerClasses)
 {
   // see header file for class documentation
   InitCTPTriggerClasses(parameter);
@@ -63,36 +64,145 @@ AliHLTCTPData::~AliHLTCTPData()
   fClassIds.Delete();
 }
 
+AliHLTCTPData::AliHLTCTPData(const AliHLTCTPData& src)
+  : TNamed(src.GetName(), src.GetTitle())
+  , AliHLTLogging()
+  , fMask(src.Mask())
+  , fTriggers(src.fTriggers)
+  , fClassIds(src.fClassIds)
+  , fCounters(src.Counters())
+{
+  // see header file for class documentation
+}
+
+AliHLTCTPData& AliHLTCTPData::operator=(const AliHLTCTPData& src)
+{
+  // see header file for class documentation
+  if (this!=&src) {
+    SetName(src.GetName());
+    SetTitle(src.GetTitle());
+    fMask=src.Mask();
+    fClassIds.Delete();
+    fClassIds.ExpandCreate(gkNCTPTriggerClasses);
+    for (int i=0; i<gkNCTPTriggerClasses; i++) {
+      ((TNamed*)fClassIds.At(i))->SetName(src.fClassIds.At(i)->GetName());
+      ((TNamed*)fClassIds.At(i))->SetTitle(src.fClassIds.At(i)->GetTitle());
+    }
+    fCounters=src.Counters();
+  }
+
+  return *this;
+}
+
+int AliHLTCTPData::Add(const AliHLTCTPData& src, int factor, int &skipped)
+{
+  // see header file for class documentation
+  
+  skipped=0;
+  for (int i=0; i<gkNCTPTriggerClasses; i++) {
+    TString c;
+    c=fClassIds.At(i)->GetName();
+    if (c.IsNull()) continue;
+    if (c.CompareTo(src.fClassIds.At(i)->GetName())==0) {
+      fCounters[i]+=factor*src.Counter(i);
+    } else {
+      skipped++;
+    }
+  }
+  return 0;
+}
+
+AliHLTCTPData& AliHLTCTPData::operator += (const AliHLTCTPData& src)
+{
+  // see header file for class documentation
+  
+  int nofInconsistencies=0;
+  Add(src, 1, nofInconsistencies);
+  if (nofInconsistencies>0) {
+    HLTError("Inconsistent operants: skipping %d of %d CTP classes for operation", nofInconsistencies, gkNCTPTriggerClasses);
+  }
+  return *this;
+}
+
+AliHLTCTPData& AliHLTCTPData::operator -= (const AliHLTCTPData& src)
+{
+  // see header file for class documentation
+  
+  int nofInconsistencies=0;
+  Add(src, -1, nofInconsistencies);
+  if (nofInconsistencies>0) {
+    HLTError("Inconsistent operants: skipping %d of %d CTP classes for operation", nofInconsistencies, gkNCTPTriggerClasses);
+  }
+  return *this;
+}
+
+AliHLTCTPData AliHLTCTPData::operator + (const AliHLTCTPData& src) const
+{
+  // see header file for class documentation
+
+  AliHLTCTPData result(*this);
+  result+=src;
+  return result;
+}
+
+AliHLTCTPData AliHLTCTPData::operator - (const AliHLTCTPData& src) const
+{
+  // see header file for class documentation
+
+  AliHLTCTPData result(*this);
+  result-=src;
+  return result;
+}
+
 int AliHLTCTPData::InitCTPTriggerClasses(const char* ctpString)
 {
   // see header file for function documentation
   if (!ctpString) return -EINVAL;
 
+  HLTImportant("Parameter: %s", ctpString);
+
   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;
+  if (string.BeginsWith("CTP_TRIGGER_CLASS=")) string.ReplaceAll("CTP_TRIGGER_CLASS=", "");
   TObjArray* classEntries=string.Tokenize(",");
   if (classEntries) {
+    enum {kBit=0, kName, kDetectors};
     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();
+           (((TObjString*)entryParams->At(kBit))->GetString()).IsDigit()) {
+         int index=(((TObjString*)entryParams->At(kBit))->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());
+           AliHLTReadoutList* pCTPClass=dynamic_cast<AliHLTReadoutList*>(fClassIds.At(index));
+           if (pCTPClass) {
+             fMask|=(AliHLTUInt64_t)0x1 << index;
+             pCTPClass->SetTitle("CTP Class");
+             pCTPClass->SetName((((TObjString*)entryParams->At(kName))->GetString()).Data());
+             TObjArray* detectors=(((TObjString*)entryParams->At(kDetectors))->GetString()).Tokenize("-");
+             if (detectors) {
+               for (int dix=0; dix<detectors->GetEntriesFast(); dix++) {
+                 if (!(((TObjString*)detectors->At(dix))->GetString()).IsDigit()) {
+                   HLTError("invalid detector list format: trigger class entry %s", entry.Data());
+                   break;
+                 }
+                 // see AliHLTReadoutList::EDetectorId for defines of detectors
+                 pCTPClass->Enable(0x1<<(((TObjString*)detectors->At(dix))->GetString()).Atoi());
+               }
+               delete detectors;
+             }
+           } else {
+           }
          } else {
            // the trigger bitfield is fixed to 50 bits (gkNCTPTriggerClasses)
-           HLTError("invalid trigger class entry %s, index width of trigger bitfield", entry.Data());
+           HLTError("invalid trigger class entry %s, index width of trigger bitfield exceeded (%d)", entry.Data(), gkNCTPTriggerClasses);
          }
        } else {
          HLTError("invalid trigger class entry %s", entry.Data());
@@ -108,7 +218,21 @@ int AliHLTCTPData::InitCTPTriggerClasses(const char* ctpString)
   return 0;
 }
 
-bool AliHLTCTPData::EvaluateCTPTriggerClass(const char* expression, AliHLTComponentTriggerData& trigData) const
+AliHLTUInt64_t AliHLTCTPData::ActiveTriggers(const AliHLTComponentTriggerData& trigData)
+{
+  // extract active triggers from the trigger data
+  if (trigData.fDataSize != sizeof(AliHLTEventTriggerData)) return (AliHLTUInt64_t)0;
+
+  // 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]&0x3ffff;
+  triggerMask<<=32;
+  triggerMask|=evtData->fCommonHeader[5];
+  return triggerMask;
+}
+
+bool AliHLTCTPData::EvaluateCTPTriggerClass(const char* expression, const AliHLTComponentTriggerData& trigData) const
 {
   // see header file for function documentation
   if (trigData.fDataSize != sizeof(AliHLTEventTriggerData)) {
@@ -118,15 +242,23 @@ bool AliHLTCTPData::EvaluateCTPTriggerClass(const char* expression, AliHLTCompon
 
   // 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];
+  AliHLTUInt64_t triggerMask=evtData->fCommonHeader[6]&0x3ffff;
   triggerMask<<=32;
   triggerMask|=evtData->fCommonHeader[5];
 
   if (fMask!=0 && (triggerMask & fMask)==0) {
-    HLTWarning("invalid trigger mask 0x%llx, unknown CTP trigger", triggerMask);
+    HLTWarning("invalid trigger mask 0x%llx, unknown CTP trigger, initialized 0x%llx", triggerMask, fMask);
+    for (int i=0; i<8; i++) HLTWarning("\t CDH[%d]=0x%lx", i, evtData->fCommonHeader[i]);
     return false;
   }
 
+  return EvaluateCTPTriggerClass(expression, triggerMask);
+}
+
+bool AliHLTCTPData::EvaluateCTPTriggerClass(const char* expression, AliHLTUInt64_t triggerMask) const
+{
+  // see header file for function documentation
+
   // 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
@@ -217,12 +349,13 @@ int AliHLTCTPData::Increment(AliHLTComponentTriggerData& trigData)
 
   // 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];
+  AliHLTUInt64_t triggerMask=evtData->fCommonHeader[6]&0x3ffff;
   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);
+    for (int i=0; i<8; i++) HLTWarning("\t CDH[%d]=0x%lx", i, evtData->fCommonHeader[i]);
   }
   Increment(triggerMask);
   return 0;
@@ -248,10 +381,44 @@ const char* AliHLTCTPData::Name(int index) const
   return fClassIds.At(index)->GetName();
 }
 
+AliHLTEventDDL AliHLTCTPData::ReadoutList(const 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));
+    AliHLTEventDDL dummy;
+    memset(&dummy, 0, sizeof(AliHLTEventDDL));
+    return dummy;
+  }
+
+  // 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]&0x3ffff;
+  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);
+    for (int i=0; i<8; i++) HLTWarning("\t CDH[%d]=0x%lx", i, evtData->fCommonHeader[i]);
+  }
+
+  // take an 'OR' of all active trigger classes 
+  AliHLTReadoutList list;
+  for (int i=0; i<gkNCTPTriggerClasses; i++) {
+    if (i>fClassIds.GetLast()) break;
+    if ((triggerMask&((AliHLTUInt64_t)0x1<<i))==0) continue;
+    AliHLTReadoutList* tcrl=(AliHLTReadoutList*)fClassIds.At(i);
+    list.OrEq(*tcrl);
+  }
+
+  return list;
+}
+
 void AliHLTCTPData::Print(Option_t* /*option*/) const
 {
   // see header file for function documentation
-  cout << "CTP counters:" << endl;
+  cout << GetTitle() << endl;
+  cout << "\tactive trigger mask: 0x" << hex << fTriggers << dec << endl;
   int count=0;
   for (int i=0; i<gkNCTPTriggerClasses; i++) {
     if (i>=Counters().GetSize()) break;