]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - HLT/BASE/AliHLTCTPData.cxx
fixed reading from OADB (M. Verweij)
[u/mrichter/AliRoot.git] / HLT / BASE / AliHLTCTPData.cxx
index 6cc17a857679771dd28700fe3c3b140295d467a7..a1bad7a2e0d8137509d6b7fbb8e62f779aa3bf25 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   *
 //* 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
-*/
+/ @file   AliHLTCTPData.cxx
+//  @author Matthias Richter
+//  @date   2009-08-20
+//  @brief  Container for CTP trigger classes and counters
+//  @note
 
 #include "AliHLTCTPData.h"
 #include "TClass.h"
-#include "TNamed.h"
 #include "TObjString.h"
 #include "TFormula.h"
+#include "AliHLTComponent.h"
+#include "AliRawDataHeader.h"
 
 /** ROOT macro for the implementation of ROOT specific class methods */
 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)
+  , fMap()
 {
+  // constructor
   // see header file for class documentation
   // or
   // refer to README to build package
@@ -50,49 +53,164 @@ 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)
+  , fMap()
 {
-  // see header file for class documentation
+  // constructor, init the CTP trigger classes
   InitCTPTriggerClasses(parameter);
 }
 
 AliHLTCTPData::~AliHLTCTPData()
 {
-  // see header file for class documentation
+  // destructor
   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())
+  , fMap()
+{
+  // copy constructor
+  ReadMap();
+}
+
+AliHLTCTPData& AliHLTCTPData::operator=(const AliHLTCTPData& src)
+{
+  // assignment operator, clone content
+  if (this!=&src) {
+    SetName(src.GetName());
+    SetTitle(src.GetTitle());
+    fMask=src.Mask();
+    fClassIds.Delete();
+    fClassIds.ExpandCreate(gkNCTPTriggerClasses);
+    for (int i=0; i<gkNCTPTriggerClasses; i++) {
+      if (i>src.fClassIds.GetLast()) break;
+      ((TNamed*)fClassIds.At(i))->SetName(src.fClassIds.At(i)->GetName());
+      ((TNamed*)fClassIds.At(i))->SetTitle(src.fClassIds.At(i)->GetTitle());
+    }
+    fCounters=src.Counters();
+  }
+
+  ReadMap();
+  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) {
-    for (int i=0; i<classEntries->GetEntries(); i++) {
+    enum {kBit=0, kName, kDetectors};
+    for (int i=0; i<classEntries->GetEntriesFast(); 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 (entryParams->GetEntriesFast()==3 &&
+           (((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());
@@ -104,47 +222,71 @@ int AliHLTCTPData::InitCTPTriggerClasses(const char* ctpString)
   }
 
   ResetCounters();
+  ReadMap();
 
   return 0;
 }
 
-bool AliHLTCTPData::EvaluateCTPTriggerClass(const char* expression, AliHLTComponentTriggerData& trigData) const
+AliHLTUInt64_t AliHLTCTPData::ActiveTriggers(const 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 false;
-  }
+  // extract active triggers from the trigger data
 
+  const AliRawDataHeader* cdh = NULL;
+  if (AliHLTComponent::ExtractTriggerData(trigData, NULL, NULL, &cdh, NULL) != 0) return (AliHLTUInt64_t)0;
+  if ((cdh->GetL1TriggerMessage() & 0x1) == 0x1) return 0x0;  // invalid for software triggers.
   // 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];
+  AliHLTUInt64_t triggerMask = cdh->GetTriggerClasses();
+  return triggerMask;
+}
+
+bool AliHLTCTPData::EvaluateCTPTriggerClass(const char* expression, const AliHLTComponentTriggerData& trigData) const
+{
+  // see header file for function documentation
+  
+  const AliRawDataHeader* cdh = NULL;
+  if (AliHLTComponent::ExtractTriggerData(trigData, NULL, NULL, &cdh, NULL, true) != 0) return false;
+  if ((cdh->GetL1TriggerMessage() & 0x1) == 0x1) return false;  // invalid for software triggers.
+  // trigger mask is 50 bit wide and is stored in word 5 and 6 of the CDH
+  AliHLTUInt64_t triggerMask = cdh->GetTriggerClasses();
 
   if (fMask!=0 && (triggerMask & fMask)==0) {
-    HLTWarning("invalid trigger mask 0x%llx, unknown CTP trigger", triggerMask);
+    AliHLTEventTriggerData* evtData=reinterpret_cast<AliHLTEventTriggerData*>(trigData.fData);
+    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
-  //
-  // 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.
+  const vector<unsigned> *pMap=&fMap;
+  vector<unsigned> tmp;
+  if (fMap.size()==0 && fClassIds.GetLast()>=0) {
+    // read map into temporary array and use it
+    ReadMap(tmp);
+    pMap=&tmp;
+    static bool suppressWarning=false;
+    if (!suppressWarning) HLTWarning("map not yet initialized, creating local map (slow), suppressing further warnings");
+    suppressWarning=true;
+  }
   vector<Double_t> par;
   TString condition=expression;
-  for (int i=0; i<gkNCTPTriggerClasses; i++) {
-    const char* className=Name(i);
+  for (unsigned index=0; index<pMap->size(); index++) {
+    const char* className=Name((*pMap)[index]);
     if (className && strlen(className)>0) {
       //HLTDebug("checking trigger class %s", className.Data());
       if (condition.Contains(className)) {
-       TString replace; replace.Form("[%d]", par.size());
+       TString replace; replace.Form("[%d]", (int)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);
+       if (triggerMask&((AliHLTUInt64_t)0x1<<(*pMap)[index])) par.push_back(1.0);
        else par.push_back(0.0);
       }
     }
@@ -173,13 +315,21 @@ int AliHLTCTPData::Index(const char* name) const
   return obj!=NULL?fClassIds.IndexOf(obj):-1;
 }
 
+int AliHLTCTPData::CheckTrigger(const char* name) const
+{
+  // check status of a trigger class
+  int index=Index(name);
+  if (index<0) return index;
+  return (fTriggers&(0x1<<index))>0?1:0;
+}
+
 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++) {
+    for (int i=0; i<classEntries->GetEntriesFast(); i++) {
       int index=Index(((TObjString*)classEntries->At(i))->GetString().Data());
       if (index>=0 && index<fCounters.GetSize()) fCounters[index]++;
     }
@@ -210,19 +360,17 @@ void AliHLTCTPData::Increment(int 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;
-  }
-
+  const AliRawDataHeader* cdh = NULL;
+  int result = AliHLTComponent::ExtractTriggerData(trigData, NULL, NULL, &cdh, NULL, true);
+  if (result != 0) return result;
+  if ((cdh->GetL1TriggerMessage() & 0x1) == 0x1) return 0;  // invalid for software triggers.
   // 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];
+  AliHLTUInt64_t triggerMask = cdh->GetTriggerClasses();
 
   if (fMask!=0 && (triggerMask & fMask)==0) {
+    AliHLTEventTriggerData* evtData=reinterpret_cast<AliHLTEventTriggerData*>(trigData.fData);
     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 +396,74 @@ const char* AliHLTCTPData::Name(int index) const
   return fClassIds.At(index)->GetName();
 }
 
+int AliHLTCTPData::ReadMap(vector<unsigned> &map) const
+{
+  // read the index map for class names
+  // for nested class names (e.g. 'myclass' is contained in
+  // 'myclassA') the longer names is added first to the map.
+  for (int index=0; index<=fClassIds.GetLast(); index++) {
+    vector<unsigned>::iterator element=map.begin();
+    for (; element!=map.end(); element++) {
+      TString name=Name(index);
+      if (name.Contains(Name(*element))) {
+       // current name contains another one already in the map
+       // -> add before and go to next entry
+       element=map.insert(element, index);
+       break;
+      }
+    }
+
+    if (element==map.end()) {
+      // unique class name, append to map
+      map.push_back(index);
+    }
+  }
+  return 0;
+}
+
+
+AliHLTReadoutList AliHLTCTPData::ReadoutList(const AliHLTComponentTriggerData& trigData) const
+{
+  // see header file for function documentation
+
+  const AliRawDataHeader* cdh = NULL;
+  if (AliHLTComponent::ExtractTriggerData(trigData, NULL, NULL, &cdh, NULL, true) != 0) return AliHLTReadoutList();
+  // Check if we are dealing with a software trigger. If so then we need to return
+  // a readout list with everything set because the CTP trigger bits are invalid.
+  // Thus we assume that everything should be read out.
+  if ((cdh->GetL1TriggerMessage() & 0x1) == 0x1) return ~ AliHLTReadoutList();
+  // trigger mask is 50 bit wide and is stored in word 5 and 6 of the CDH
+  AliHLTUInt64_t triggerMask = cdh->GetTriggerClasses();
+
+  if (fMask!=0 && (triggerMask & fMask)==0) {
+    AliHLTEventTriggerData* evtData=reinterpret_cast<AliHLTEventTriggerData*>(trigData.fData);
+    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 ReadoutList(triggerMask);
+}
+
+AliHLTReadoutList AliHLTCTPData::ReadoutList(AliHLTUInt64_t  triggerMask) const
+{
+  // 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;