Fixing bug in AliHLTRunSummary and AliHLTEventSummary, need to have version number...
authoraszostak <aszostak@f7af4fe6-9843-0410-8265-dc069ae4e863>
Sun, 1 Nov 2009 18:01:41 +0000 (18:01 +0000)
committeraszostak <aszostak@f7af4fe6-9843-0410-8265-dc069ae4e863>
Sun, 1 Nov 2009 18:01:41 +0000 (18:01 +0000)
Fixing bug in AliHLTGlobalTriggerComponent to generate correctly trigger menu evaluation logic for trailing operators.
Fixing AliHLTGlobalTriggerWrapper to catch CINT errors correctly.
Fixing bug removing registrations in AliHLTConfiguration.
Adding more documentation.

HLT/BASE/AliHLTConfiguration.cxx
HLT/BASE/AliHLTTriggerMenu.h
HLT/CMake_libAliHLTTrigger.txt
HLT/trigger/AliHLTEventSummary.h
HLT/trigger/AliHLTGlobalTrigger.h
HLT/trigger/AliHLTGlobalTriggerComponent.cxx
HLT/trigger/AliHLTGlobalTriggerWrapper.cxx
HLT/trigger/AliHLTGlobalTriggerWrapper.h
HLT/trigger/AliHLTRunSummary.h
HLT/trigger/test/TriggerConfig.C
HLT/trigger/test/testGlobalTriggerComponent.C

index 438020efb80dbc81cd30b75864caf0e6cc3771c1..dde017d3a3ff1b5f69b0fc6c294e39d218177d6c 100644 (file)
@@ -131,7 +131,11 @@ AliHLTConfiguration::~AliHLTConfiguration()
   // see header file for function documentation
   if (fgConfigurationHandler) {
     if (fgConfigurationHandler->FindConfiguration(fID.Data())!=NULL) {
-      fgConfigurationHandler->RemoveConfiguration(this);
+      // 30 Dec 2009 - Cannot use the 'this' pointer in the RemoveConfiguration
+      // method since the fgConfigurationHandler contains clone objects and therefor
+      // the remove method will not find this object in the list to remove.
+      //fgConfigurationHandler->RemoveConfiguration(this);
+      fgConfigurationHandler->RemoveConfiguration(fID.Data());
     }
   }
   if (fArgv != NULL) {
index ac2899f19752ace59bac8903f6c9037c1543deae..e72c34892b396d844e0d844eb052b08285920c53 100644 (file)
  * domain merging expressions) are allowed to have a dangling trailing operator.
  * The trailing operator will then make sense in the full concatenated expression.
  * If no such trailing operator is found then the default trigger conditions operator
- * is used implicitly, as defined in the trigger menu.
+ * is used implicitly for the concatenation, as defined in the trigger menu.
  * If the full concatenated condition expression evaluates to true then the priority
  * group's result is also true and the output trigger domain can be calculated.
  * This is done by taking all the merging expressions from only those trigger menu
  * items whose trigger condition expression fragments were true, and concatenating
  * those merging expression fragments together to arrive at the full merging expression.
  * The final trigger domain is calculated by evaluating the merging expression.
- * Note that the concatenation of the merging expression fragments working in the
+ * Note that the concatenation of the merging expression fragments works in the
  * same manner as the trigger condition expressions. So a trailing operator is
  * allowed in each trigger menu item's merging expression, and is implicitly removed
- * if not needed, but used to concatenate with the next expression required.
+ * if not needed, but used to concatenate with the next triggered expression.
  * The default domain merging operator is used if no trailing operator is present
  * but a concatenation is required.
  * The evaluation of trigger menu items stops at the first priority group whose
index 2768a50dddb8beb7f7b112e377c92e9b9005c727..f65d3208e26c4eefde2b020d4e5f0897fb5b6f52 100644 (file)
@@ -3,6 +3,7 @@
 set(SRCS
 trigger/AliHLTTrigger.cxx
 trigger/AliHLTGlobalTrigger.cxx
+trigger/AliHLTGlobalTriggerWrapper.cxx
 trigger/AliHLTGlobalTriggerConfig.cxx
 trigger/AliHLTGlobalTriggerComponent.cxx
 trigger/AliHLTTriggerBarrelMultiplicity.cxx
index aee8868b07631bd2e46949919954926aaa59bb5c..49827f72805a62b7b79b71428a9aa2b1adf25819 100644 (file)
@@ -138,7 +138,7 @@ private:
   /** Detector run statistics classes */
   TObjArray* fDetectorArray;                     //! transient
 
-  ClassDef(AliHLTEventSummary, 0);
+  ClassDef(AliHLTEventSummary, 1);
 
 };
 #endif
index 1d228a5be08d3799875d6c3b9156c740697e4f39..ad7462a7c35363d9b19bc1beee7b712faecb64a3 100644 (file)
@@ -78,6 +78,14 @@ class AliHLTGlobalTrigger
    */
   virtual void SetCounters(const TArrayL64& counters) = 0;
   
+  /**
+   * Method for checking if the last call to one of the AliHLTGlobalTrigger
+   * methods failed. This is used by the AliHLTGlobalTriggerWrapper to indicate
+   * if the CINT interpreter had problems with the interpreted class.
+   * \returns true if there was a problem with the method call.
+   */
+  virtual bool CallFailed() const { return false; }
+  
   /**
    * Creates a new instance of a particular global trigger class.
    * \param name  The name of the class to create.
index 698b08f25985bd58dd91ec583ce4c6d05c0bb108..d56c588bcb5770cedf64c7bf899df665422cb81d 100644 (file)
@@ -258,6 +258,7 @@ Int_t AliHLTGlobalTriggerComponent::DoInit(int argc, const char** argv)
   }
   
   fTrigger->FillFromMenu(*menu);
+  if (fTrigger->CallFailed()) return -EPROTO;
 
   // setup the CTP accounting in AliHLTComponent
   SetupCTPData();
@@ -328,14 +329,17 @@ int AliHLTGlobalTriggerComponent::DoTrigger()
   // Copy the trigger counters in case we need to set them back to their original
   // value because the PushBack method fails with ENOSPC.
   TArrayL64 originalCounters = fTrigger->GetCounters();
+  if (fTrigger->CallFailed()) return -EPROTO;
   
   fTrigger->NewEvent();
+  if (fTrigger->CallFailed()) return -EPROTO;
   
   // Fill in the input data.
   const TObject* obj = GetFirstInputObject();
   while (obj != NULL)
   {
     fTrigger->Add(obj, GetDataType(), GetSpecification());
+    if (fTrigger->CallFailed()) return -EPROTO;
     obj = GetNextInputObject();
   }
 
@@ -350,6 +354,7 @@ int AliHLTGlobalTriggerComponent::DoTrigger()
   TString description;
   AliHLTTriggerDomain triggerDomain;
   bool triggerResult = fTrigger->CalculateTriggerDecision(triggerDomain, description);
+  if (fTrigger->CallFailed()) return -EPROTO;
   AliHLTGlobalTriggerDecision decision(
       triggerResult,
       // The following will cause the decision to be generated with default values
@@ -370,6 +375,8 @@ int AliHLTGlobalTriggerComponent::DoTrigger()
   }
 
   decision.SetCounters(fTrigger->GetCounters(), GetEventCount()+1);
+  if (fTrigger->CallFailed()) return -EPROTO;
+  
   static UInt_t lastTime=0;
   TDatime time;
   if (time.Get()-lastTime>5) {
@@ -405,6 +412,7 @@ int AliHLTGlobalTriggerComponent::DoTrigger()
     fBufferSizeConst += 1024*1024;
     fBufferSizeMultiplier *= 2.;
     fTrigger->SetCounters(originalCounters);
+    if (fTrigger->CallFailed()) return -EPROTO;
     return -ENOSPC;
   }
   return 0;
@@ -454,6 +462,7 @@ int AliHLTGlobalTriggerComponent::Reconfigure(const char* cdbEntry, const char*
   
   fTrigger = trigger;
   fTrigger->FillFromMenu(*menu);
+  if (fTrigger->CallFailed()) return -EPROTO;
 
   // Set the default values from the trigger menu.
   SetDescription(menu->DefaultDescription());
@@ -666,6 +675,10 @@ int AliHLTGlobalTriggerComponent::GenerateTrigger(
     code << "    HLTDebug(Form(\"Filling domain entries from trigger menu symbols for global trigger %p.\", this));" << endl;
   }
   code << "    for (Int_t i = 0; i < menu.SymbolArray().GetEntriesFast(); i++) {" << endl;
+  // 30 Oct 2009 - CINT sometimes evaluates the dynamic_cast incorrectly.
+  // Have to use the TClass system for extra protection.
+  code << "      if (menu.SymbolArray().UncheckedAt(i) == NULL) continue;" << endl;
+  code << "      if (menu.SymbolArray().UncheckedAt(i)->IsA() != AliHLTTriggerMenuSymbol::Class()) continue;" << endl;
   code << "      const AliHLTTriggerMenuSymbol* symbol = dynamic_cast<const"
            " AliHLTTriggerMenuSymbol*>(menu.SymbolArray().UncheckedAt(i));" << endl;
   code << "      if (symbol == NULL) continue;" << endl;
@@ -765,7 +778,10 @@ int AliHLTGlobalTriggerComponent::GenerateTrigger(
              << symbol->Name() << "DomainEntry.AsString().Data()));" << endl;
       }
     }
-    code << "    const " << symbol->ObjectClass() << "* " << symbol->Name()
+    // 30 Oct 2009 - CINT sometimes evaluates the dynamic_cast incorrectly.
+    // Have to use the TClass system for extra protection.
+    code << "    const " << symbol->ObjectClass() << "* " << symbol->Name() << "_object_ = NULL;" << endl;
+    code << "    if (_object_->IsA() == " << symbol->ObjectClass() << "::Class()) " << symbol->Name()
          << "_object_ = dynamic_cast<const " << symbol->ObjectClass()
          << "*>(_object_);" << endl;
     code << "    if (" << symbol->Name() << "_object_ != NULL && ";
@@ -954,33 +970,19 @@ int AliHLTGlobalTriggerComponent::GenerateTrigger(
       }
       else
       {
-        bool switchWillBeEmpty = true;
-        for (size_t k = 0; k < m; k++)
-        {
-          if (conditionOperator[k] == "") continue;
-          switchWillBeEmpty = false;
-        }
-        if (switchWillBeEmpty)
+        if (conditionOperator[m-1] == "")
         {
           code << "    _group_result_ = _group_result_ "
                << menu->DefaultConditionOperator() << " _item_result_;" << endl;
         }
         else
         {
-          code << "    switch(_previous_match_) {" << endl;
-          for (size_t k = 0; k < m; k++)
-          {
-            if (conditionOperator[k] == "") continue;
-            code << "    case " << k << ": _group_result_ = _group_result_ "
-                 << conditionOperator[k] << " _item_result_; break;" << endl;
-          }
-          code << "    default: _group_result_ = _group_result_ "
-               << menu->DefaultConditionOperator() << " _item_result_;" << endl;
-          code << "    }" << endl;
+          code << "    _group_result_ = _group_result_ "
+               << conditionOperator[m-1] << " _item_result_;" << endl;
         }
         code << "    if (_item_result_) {" << endl;
         code << "      if (_trigger_matched_) {" << endl;
-        switchWillBeEmpty = true;
+        bool switchWillBeEmpty = true;
         for (size_t k = 0; k < m; k++)
         {
           if (domainOperator[k] == "") continue;
@@ -1343,8 +1345,10 @@ int AliHLTGlobalTriggerComponent::PrintStatistics(const AliHLTGlobalTrigger* pTr
 {
   // print some statistics
   int totalEvents=GetEventCount()+offset;
-  for (int i=0; i<pTrigger->GetCounters().GetSize(); i++) {
-    ULong64_t count=pTrigger->GetCounters()[i];
+  const TArrayL64& counters = pTrigger->GetCounters();
+  if (pTrigger->CallFailed()) return -EPROTO;
+  for (int i = 0; i < counters.GetSize(); i++) {
+    ULong64_t count = counters[i];
     float ratio=0;
     if (totalEvents>0) ratio=100*(float)count/totalEvents;
     HLTLog(level, "Item %d: total events: %d - counted events: %llu (%.1f%%)", i, totalEvents, count, ratio);
@@ -1395,6 +1399,7 @@ int AliHLTGlobalTriggerComponent::AddCTPDecisions(AliHLTGlobalTrigger* pTrigger,
     else pDecision->TriggerDomain().Add(pCTPData->ReadoutList());
 
     pTrigger->Add(fCTPDecisions->At(i), kAliHLTDataTypeTriggerDecision, kAliHLTVoidDataSpec);
+    if (pTrigger->CallFailed()) return -EPROTO;
   }
 
   return 0;
index 22eae9045814c74d7a7a1e5056dafe8e7bbfe97b..1bffc87e6c8dbdaba80c8ee55734d3598a5b29e2 100644 (file)
 ClassImp(AliHLTGlobalTriggerWrapper)
 
 
+namespace
+{
+  /// Variable to store the error message if an error occured in CINT when interpreting code.
+  TString gCINTErrorMessage = "";
+  
+  /**
+   * This routine is the callback for the CINT interpreter when it finds a syntax error
+   * in the source code generated by the AliHLTGlobalTriggerComponent class.
+   */
+  void AliHLTOnErrorInCINT(char* message)
+  {
+    gCINTErrorMessage += message;
+  }
+
+} // end of namespace
+
+
 AliHLTGlobalTriggerWrapper::AliHLTGlobalTriggerWrapper(const char* classname) :
   AliHLTGlobalTrigger(),
   AliHLTLogging(),
@@ -49,7 +66,8 @@ AliHLTGlobalTriggerWrapper::AliHLTGlobalTriggerWrapper(const char* classname) :
   fAddCall(),
   fCalculateTriggerDecisionCall(),
   fGetCountersCall(),
-  fSetCountersCall()
+  fSetCountersCall(),
+  fCallFailed(false)
 {
   // The default constructor.
   
@@ -100,6 +118,8 @@ AliHLTGlobalTriggerWrapper::AliHLTGlobalTriggerWrapper(const char* classname) :
   {
     HLTError("Could not create a new object of type '%s'.", classname);
   }
+  
+  G__set_errmsgcallback(reinterpret_cast<void*>(AliHLTOnErrorInCINT));
 }
 
 
@@ -115,24 +135,20 @@ void AliHLTGlobalTriggerWrapper::FillFromMenu(const AliHLTTriggerMenu& menu)
 {
   // Fills internal values from the trigger menu.
   
+  fCallFailed = false;
   struct Params
   {
     const void* fMenu;
   } params;
   params.fMenu = &menu;
   fFillFromMenuCall.SetParamPtrs(&params, 1);
+  gCINTErrorMessage = "";
   fFillFromMenuCall.Execute(fObject);
-  int error = G__lasterror();
-  if (error != TInterpreter::kNoError)
+  if (gCINTErrorMessage != "")
   {
-    if (error == TInterpreter::kFatal)
-    {
-      HLTFatal("Error interpreting the code for class '%s' at line %d.", fClass->GetName(), G__lasterror_linenum());
-    }
-    else
-    {
-      HLTError("Error interpreting the code for class '%s' at line %d.", fClass->GetName(), G__lasterror_linenum());
-    }
+    fCallFailed = true;
+    HLTError(gCINTErrorMessage.Data());
+    HLTFatal("Error interpreting the code for class '%s' at line %d.", fClass->GetName(), G__lasterror_linenum());
   }
 }
 
@@ -141,18 +157,14 @@ void AliHLTGlobalTriggerWrapper::NewEvent()
 {
   // Clears the internal buffers for a new event.
 
+  fCallFailed = false;
+  gCINTErrorMessage = "";
   fNewEventCall.Execute(fObject);
-  int error = G__lasterror();
-  if (error != TInterpreter::kNoError)
+  if (gCINTErrorMessage != "")
   {
-    if (error == TInterpreter::kFatal)
-    {
-      HLTFatal("Error interpreting the code for class '%s' at line %d.", fClass->GetName(), G__lasterror_linenum());
-    }
-    else
-    {
-      HLTError("Error interpreting the code for class '%s' at line %d.", fClass->GetName(), G__lasterror_linenum());
-    }
+    fCallFailed = true;
+    HLTError(gCINTErrorMessage.Data());
+    HLTFatal("Error interpreting the code for class '%s' at line %d.", fClass->GetName(), G__lasterror_linenum());
   }
 }
 
@@ -164,6 +176,7 @@ void AliHLTGlobalTriggerWrapper::Add(
 {
   // Adds parameters from the object to the internal buffers and variables.
   
+  fCallFailed = false;
   struct Params
   {
     const void* fObj;
@@ -174,18 +187,13 @@ void AliHLTGlobalTriggerWrapper::Add(
   params.fType = &type;
   params.fSpec = spec;
   fAddCall.SetParamPtrs(&params, 3);
+  gCINTErrorMessage = "";
   fAddCall.Execute(fObject);
-  int error = G__lasterror();
-  if (error != TInterpreter::kNoError)
+  if (gCINTErrorMessage != "")
   {
-    if (error == TInterpreter::kFatal)
-    {
-      HLTFatal("Error interpreting the code for class '%s' at line %d.", fClass->GetName(), G__lasterror_linenum());
-    }
-    else
-    {
-      HLTError("Error interpreting the code for class '%s' at line %d.", fClass->GetName(), G__lasterror_linenum());
-    }
+    fCallFailed = true;
+    HLTError(gCINTErrorMessage.Data());
+    HLTFatal("Error interpreting the code for class '%s' at line %d.", fClass->GetName(), G__lasterror_linenum());
   }
 }
 
@@ -194,6 +202,7 @@ bool AliHLTGlobalTriggerWrapper::CalculateTriggerDecision(AliHLTTriggerDomain& d
 {
   // Calculates the global trigger decision.
 
+  fCallFailed = false;
   struct Params
   {
     const void* fDomain;
@@ -203,18 +212,14 @@ bool AliHLTGlobalTriggerWrapper::CalculateTriggerDecision(AliHLTTriggerDomain& d
   params.fDesc = &description;
   fCalculateTriggerDecisionCall.SetParamPtrs(&params, 2);
   Long_t retval;
+  gCINTErrorMessage = "";
   fCalculateTriggerDecisionCall.Execute(fObject, retval);
-  int error = G__lasterror();
-  if (error != TInterpreter::kNoError)
+  if (gCINTErrorMessage != "")
   {
-    if (error == TInterpreter::kFatal)
-    {
-      HLTFatal("Error interpreting the code for class '%s' at line %d.", fClass->GetName(), G__lasterror_linenum());
-    }
-    else
-    {
-      HLTError("Error interpreting the code for class '%s' at line %d.", fClass->GetName(), G__lasterror_linenum());
-    }
+    fCallFailed = true;
+    HLTError(gCINTErrorMessage.Data());
+    HLTFatal("Error interpreting the code for class '%s' at line %d.", fClass->GetName(), G__lasterror_linenum());
+    return false;
   }
   return bool(retval);
 }
@@ -225,18 +230,13 @@ const TArrayL64& AliHLTGlobalTriggerWrapper::GetCounters() const
   // Returns the internal counter array.
 
   Long_t retval = 0x0;
+  gCINTErrorMessage = "";
   fGetCountersCall.Execute(fObject, retval);
-  int error = G__lasterror();
-  if (error != TInterpreter::kNoError)
+  if (gCINTErrorMessage != "")
   {
-    if (error == TInterpreter::kFatal)
-    {
-      HLTFatal("Error interpreting the code for class '%s' at line %d.", fClass->GetName(), G__lasterror_linenum());
-    }
-    else
-    {
-      HLTError("Error interpreting the code for class '%s' at line %d.", fClass->GetName(), G__lasterror_linenum());
-    }
+    fCallFailed = true;
+    HLTError(gCINTErrorMessage.Data());
+    HLTFatal("Error interpreting the code for class '%s' at line %d.", fClass->GetName(), G__lasterror_linenum());
   }
   static const TArrayL64 emptyArray;
   const TArrayL64* ptr = &emptyArray; // Make sure we do not return a NULL pointer.
@@ -249,24 +249,20 @@ void AliHLTGlobalTriggerWrapper::SetCounters(const TArrayL64& counters)
 {
   // Fills the internal counter array with new values.
   
+  fCallFailed = false;
   struct Params
   {
     const void* fCounters;
   } params;
   params.fCounters = &counters;
   fSetCountersCall.SetParamPtrs(&params, 1);
+  gCINTErrorMessage = "";
   fSetCountersCall.Execute(fObject);
-  int error = G__lasterror();
-  if (error != TInterpreter::kNoError)
+  if (gCINTErrorMessage != "")
   {
-    if (error == TInterpreter::kFatal)
-    {
-      HLTFatal("Error interpreting the code for class '%s' at line %d.", fClass->GetName(), G__lasterror_linenum());
-    }
-    else
-    {
-      HLTError("Error interpreting the code for class '%s' at line %d.", fClass->GetName(), G__lasterror_linenum());
-    }
+    fCallFailed = true;
+    HLTError(gCINTErrorMessage.Data());
+    HLTFatal("Error interpreting the code for class '%s' at line %d.", fClass->GetName(), G__lasterror_linenum());
   }
 }
 
index a3ee287b63d7b7ef0ee07007f8b51bbba894631a..c66a7671149cbf96d966eeb1fdafbdde03a81f90 100644 (file)
@@ -85,6 +85,13 @@ class AliHLTGlobalTriggerWrapper : public AliHLTGlobalTrigger, public AliHLTLogg
    * \param counters  The array of trigger counters to use.
    */
   virtual void SetCounters(const TArrayL64& counters);
+  
+  /**
+   * Indicates if the CINT interpreter had problems with the interpreted class
+   * during a call to one of the interface methods overloaded from AliHLTGlobalTrigger.
+   * \returns true if there was a problem with the method call.
+   */
+  virtual bool CallFailed() const { return fCallFailed; }
 
   /// Returns true if the wrapper object has setup the underlying object class properly.
   bool IsValid() const;
@@ -104,6 +111,7 @@ class AliHLTGlobalTriggerWrapper : public AliHLTGlobalTrigger, public AliHLTLogg
   TMethodCall fCalculateTriggerDecisionCall;  /// Method call object for CalculateTriggerDecision method.
   mutable TMethodCall fGetCountersCall;  /// Method call object for GetCounters method.
   TMethodCall fSetCountersCall;  /// Method call object for SetCounters method.
+  mutable bool fCallFailed;  /// Indicates if the last method call failed or not.
   
   ClassDef(AliHLTGlobalTriggerWrapper, 0) // Wrapper class to interface with an interpreted global trigger class.
 };
index b6146c9c07fdd4e1bab1b266f590982e2023bb27..c2e208d0518d6935ac7f72f7a4eadfb5208738af 100644 (file)
@@ -156,6 +156,6 @@ private:
   /** Detector run statistics classes */
   TObjArray* fDetectorArray;                     //! transient
 
-  ClassDef(AliHLTRunSummary, 0);  
+  ClassDef(AliHLTRunSummary, 1);  
 };
 #endif
index 0d45d05c53970d6c2f72d7269f67482d29044889..fac0ff644a73358b665cd31d694b9bfbc4d446c7 100644 (file)
@@ -58,9 +58,11 @@ void SingleGroupTestConfig()
 void PrescalarTestConfig()
 {
        AliHLTGlobalTriggerConfig config("Prescalar test config");
-       config.AddItem(2, "triggerTPC", "triggerTPC", 2, "TPC trigger");
+       config.AddItem(2, "triggerTPC", "triggerTPC", 3, "TPC trigger");
        config.AddItem(1, "triggerMUON", "triggerMUON", "MUON trigger");
        config.SetDefaultConditionOperator("||");
+       config.SetDefaultTriggerDescription("No trigger");
+       config.SetDefaultTriggerDomain(AliHLTTriggerDomain("*******:HLT "));
 }
 
 /**
@@ -70,9 +72,13 @@ void SymbolTestConfig()
 {
        AliHLTGlobalTriggerConfig config("Symbol test config");
        config.AddSymbol("domain-All", "AliHLTTriggerDomain", "", "AliHLTTriggerDomain(\"*******:***,-DAQRDOUT:TST\")");
+       config.AddSymbol("PHOSclusters", "AliHLTTriggerDomain", "", "AliHLTTriggerDomain(\"CLUSTERS:PHOS\")");
+       config.AddSymbol("PHOStracks", "AliHLTTriggerDomain", "", "AliHLTTriggerDomain(\"TRACKS:PHOS\")");
+       config.AddSymbol("domainPHOS", "AliHLTTriggerDomain", "", "PHOSclusters | PHOStracks");
+       config.AddSymbol("triggerTPC", "bool", "this->Result()", "false", "AliHLTTriggerDecision");
        config.AddSymbol("trigClasses", "AliHLTUInt64_t", "this->GetTriggerClasses()", "0x0", "AliHLTEventSummary");
-       config.AddItem(2, "true", "domain-All", 5, "Pass through");
-       config.AddItem(1, "trigClasses == 0x2", "domain-All", "Trigger class 2");
+       config.AddItem(2, "true", "domain-All", 4, "Pass through");
+       config.AddItem(1, "trigClasses == 0x2", "triggerTPC | domainPHOS", "Trigger class 2");
 }
 
 /**
@@ -83,11 +89,17 @@ void ComplexTestConfig()
 {
        AliHLTGlobalTriggerConfig config("Complex test config");
        config.AddSymbol("domain-All", "AliHLTTriggerDomain", "", "AliHLTTriggerDomain(\"*******:***,-DAQRDOUT:TST\")");
-       config.AddItem(3, "true", "domain-All", 5, "Pass through");
-       config.AddItem(2, "triggerSSD", "triggerSSD", "SSD trigger");
-       config.AddItem(2, "triggerMUON", "triggerMUON", "MUON trigger");
+       config.AddSymbol("PHOSclusters", "AliHLTTriggerDomain", "", "AliHLTTriggerDomain(\"CLUSTERS:PHOS\")");
+       config.AddSymbol("PHOStracks", "AliHLTTriggerDomain", "", "AliHLTTriggerDomain(\"TRACKS:PHOS\")");
+       config.AddSymbol("domainPHOS", "AliHLTTriggerDomain", "", "PHOSclusters | PHOStracks");
+       config.AddItem(4, "true", "domain-All", 7, "Pass through");
+       config.AddItem(3, "triggerSSD", "triggerSSD |", "SSD trigger 1");
+       config.AddItem(3, "triggerMUON", "triggerMUON", "MUON trigger 1");
+       config.AddItem(2, "triggerSSD ||", "triggerSSD | domainPHOS", "SSD trigger 2");
+       config.AddItem(2, "triggerMUON ||", "triggerMUON", "MUON trigger 2");
        config.AddItem(1, "triggerTPC", "triggerTPC | triggerSSD | triggerMUON", "Slow trigger");
-       config.SetDefaultDomain(AliHLTTriggerDomain("*******:MUON"));
+       config.SetDefaultTriggerDomain(AliHLTTriggerDomain("*******:MUON"));
+       config.SetDefaultConditionOperator("&&");
 }
 
 /**
index 290928c73643d19e074e743acc3bc41540b73945..b4bc00185a2fcb5f8ffb502b72cdc41ffd5f27ea 100644 (file)
  * This macro is used to test the AliHLTGlobalTriggerComponent class.
  * A number of tests are run with the AliHLTSystem framework to check that
  * the automatically generated global trigger logic is generated correctly.
+ *
+ * This macro can also be used to debug the configuration that fails.
+ * If a configuration test fails then the global trigger logic implementation
+ * is left in a generated file with a name of the form \<AliHLTGlobalTriggerImpl_*.cxx\>.
+ * For example a file named like: AliHLTGlobalTriggerImpl_08869e64_c54b_11de_9717_0101007fbeef.cxx
+ * One can make manual modifications to this file and then rerun the test with
+ * these manual modifications with the following command in aliroot:
+ *  .x testGlobalTriggerComponent.C+(\<configVersion\>,"\<AliHLTGlobalTriggerImpl_*\>")
+ * where \<configVersion\> is the appropriate config version number as passed to the
+ * TriggerConfig.C file to initialise the configuration we want to test. Also take note
+ * that we only specify the root of the file name without the .cxx file name extention.
+ * For our example file name the command to execute in aliroot would be:
+ *  .x testGlobalTriggerComponent.C+(2,"AliHLTGlobalTriggerImpl_08869e64_c54b_11de_9717_0101007fbeef")
+ * where we are testing the 2nd trigger configuration in TriggerConfig.C.
  */
 
 #if defined(__CINT__) && (! defined(__MAKECINT__))
-#error This macro must be compiled. Try running as testGlobalTriggerComponent.C++
+#error This macro must be compiled. Try running as testGlobalTriggerComponent.C++, but remember to load the libAliHLTTrigger.so library first.
 #endif
 
 #if !defined(__CINT__) || defined(__MAKECINT__)
@@ -37,9 +51,9 @@
 #include "AliHLTTriggerDomain.h"
 #include "AliHLTTriggerDecision.h"
 #include "AliHLTGlobalTriggerDecision.h"
+#include "AliHLTEventSummary.h"
 #include "AliHLTSystem.h"
 #include "AliHLTConfiguration.h"
-#include "AliHLTConfigurationHandler.h"
 #include "Riostream.h"
 #endif
 
  */
 void GenerateInputData()
 {
+       bool loadedLibs = false;
        if (gClassTable->GetID("AliHLTGlobalTriggerComponent") < 0)
        {
                gSystem->Load("libAliHLTUtil.so");
                gSystem->Load("libAliHLTTRD.so");
                gSystem->Load("libAliHLTTrigger.so");
+               loadedLibs = true;
        }
 
        AliHLTReadoutList readoutList1("TPC");
@@ -77,41 +93,61 @@ void GenerateInputData()
        triggerDomain3.Add(readoutList3);
        AliHLTTriggerDecision decision3(true, "triggerSSD", triggerDomain3, "SSD has data");
        
+       AliHLTEventSummary summary1;
+       summary1.SetTriggerClass(0x1);
+       
+       AliHLTEventSummary summary2;
+       summary2.SetTriggerClass(0x2);
+       
        TFile* file = new TFile("testInputFile1.root", "RECREATE");
        decision1.Write("triggerTPC");
        decision2.Write("triggerMUON");
        decision3.Write("triggerSSD");
+       summary2.Write("summary");
        delete file;
        
        file = new TFile("testInputFile2.root", "RECREATE");
        decision1.Write("triggerTPC");
+       summary2.Write("summary");
        delete file;
        
        file = new TFile("testInputFile3.root", "RECREATE");
        decision2.Write("triggerMUON");
+       summary1.Write("summary");
        delete file;
        
        file = new TFile("testInputFile4.root", "RECREATE");
        decision3.Write("triggerSSD");
+       summary2.Write("summary");
        delete file;
        
        file = new TFile("testInputFile5.root", "RECREATE");
        decision1.Write("triggerTPC");
        decision2.Write("triggerMUON");
+       summary1.Write("summary");
        delete file;
        
        file = new TFile("testInputFile6.root", "RECREATE");
        decision1.Write("triggerTPC");
        decision3.Write("triggerSSD");
+       summary2.Write("summary");
        delete file;
        
        file = new TFile("testInputFile7.root", "RECREATE");
        decision2.Write("triggerMUON");
        decision3.Write("triggerSSD");
+       summary1.Write("summary");
        delete file;
        
        file = new TFile("testInputFile8.root", "RECREATE");
        delete file;
+       
+       if (loadedLibs)
+       {
+               gSystem->Unload("libAliHLTTrigger.so");
+               gSystem->Unload("libAliHLTTRD.so");
+               gSystem->Unload("libAliHLTUtil.so");
+       }
 }
 
 /**
@@ -129,15 +165,14 @@ void GenerateInputData()
  */
 void RunTrigger(int config = 0, bool usecint = false, bool debug = false, int numOfEvents = 8, const char* customClass = NULL)
 {
-       AliHLTSystem sys;
-       sys.fpConfigurationHandler->SetLocalLoggingLevel(kHLTLogAll);
-       sys.LoadComponentLibraries("libAliHLTUtil.so");
-       sys.LoadComponentLibraries("libAliHLTTRD.so");
-       sys.LoadComponentLibraries("libAliHLTTrigger.so");
+       AliHLTSystem gHLTSystem;
+       gHLTSystem.LoadComponentLibraries("libAliHLTUtil.so");
+       gHLTSystem.LoadComponentLibraries("libAliHLTTRD.so");
+       gHLTSystem.LoadComponentLibraries("libAliHLTTrigger.so");
        if (debug)
        {
                AliLog::SetGlobalLogLevel(AliLog::kMaxType);
-               sys.SetGlobalLoggingLevel(kHLTLogAll);
+               gHLTSystem.SetGlobalLoggingLevel(kHLTLogAll);
        }
        
        TString cmdline = "-datatype ROOTTOBJ 'HLT ' ";
@@ -159,8 +194,43 @@ void RunTrigger(int config = 0, bool usecint = false, bool debug = false, int nu
        
        AliHLTConfiguration sink("sink", "ROOTFileWriter", "proc", "-datafile testOutputFile.root -concatenate-events");
        
-       sys.BuildTaskList("sink");
-       sys.Run(numOfEvents);
+       gHLTSystem.BuildTaskList("sink");
+       gHLTSystem.Run(numOfEvents);
+}
+
+/**
+ * This method calls the RunTrigger method in an independant aliroot process.
+ * This is necessary since we get memory corruption if we run too many instances of
+ * AliHLTSystem in the same process.
+ */
+void CallRunTrigger(
+               int config = 0, bool usecint = false, bool debug = false,
+               int numOfEvents = 8, const char* customClass = NULL,
+               bool showOutput = false
+       )
+{
+       const char* redirection = "> /dev/null";
+       const char* classNameString = "NULL";
+       if (showOutput) redirection = "";
+       if (customClass != NULL) classNameString = Form("\"%s\"", customClass);
+       const char* command = Form(
+                       "aliroot %s <<EOF\n"
+                       "gSystem->Load(\"libAliHLTUtil.so\");\n"
+                       "gSystem->Load(\"libAliHLTTRD.so\");\n"
+                       "gSystem->Load(\"libAliHLTTrigger.so\");\n"
+                       "gSystem->SetIncludePath(\"-I${ALICE_ROOT}/include"
+                       " -I${ALICE_ROOT}/HLT/BASE -I${ALICE_ROOT}/HLT/trigger\");\n"
+                       ".L testGlobalTriggerComponent.C+\n"
+                       "RunTrigger(%d,%d,%d,%d,%s);\n"
+                       "EOF\n",
+                       redirection,
+                       config,
+                       usecint,
+                       debug,
+                       numOfEvents,
+                       classNameString
+               );
+       gSystem->Exec(command);
 }
 
 /**
@@ -348,6 +418,203 @@ cleanup:
 }
 
 
+/// Routine for checking the result of the PrescalarTestConfig() config in TriggerConfig.C
+bool CheckPrescalarTestConfig(const char* testName = "Prescalar config")
+{
+       AliHLTGlobalTriggerDecision* decision = NULL;
+       bool result = false;
+       
+       AliHLTTriggerDomain domainTPC("CLUSTERS:TPC ,TRACKS:TPC ");
+       domainTPC.Add(AliHLTReadoutList("TPC"));
+       AliHLTTriggerDomain domainMUON("TRACKS:MUON");
+       domainMUON.Add(AliHLTReadoutList("MUONTRK"));
+       domainMUON.Add(AliHLTReadoutList("MUONTRG"));
+       AliHLTTriggerDomain domainSSD("*******:SSD ");
+       domainSSD.Add(AliHLTReadoutList("ITSSSD"));
+       AliHLTTriggerDomain defaultDomain("*******:HLT ");
+
+       TFile* file = new TFile("testOutputFile.root", "READ");
+       
+       // Triggers in events (i.e. input triggers):
+       // event 1: TPC MUON SSD
+       // event 2: TPC
+       // event 3: MUON
+       // event 4: SSD
+       // event 5: TPC MUON
+       // event 6: TPC SSD
+       // event 7: MUON SSD
+       // event 8: (empty)
+       decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;1"));
+       result = Check(testName, 1, decision, true, domainTPC, "TPC trigger");
+       if (! result) goto cleanup;
+       decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;2"));
+       result = Check(testName, 2, decision, false, defaultDomain, "No trigger");
+       if (! result) goto cleanup;
+       decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;3"));
+       result = Check(testName, 3, decision, true, domainMUON, "MUON trigger");
+       if (! result) goto cleanup;
+       decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;4"));
+       result = Check(testName, 4, decision, false, defaultDomain, "No trigger");
+       if (! result) goto cleanup;
+       decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;5"));
+       result = Check(testName, 5, decision, true, domainMUON, "MUON trigger");
+       if (! result) goto cleanup;
+       decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;6"));
+       result = Check(testName, 6, decision, true, domainTPC, "TPC trigger");
+       if (! result) goto cleanup;
+       decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;7"));
+       result = Check(testName, 7, decision, true, domainMUON, "MUON trigger");
+       if (! result) goto cleanup;
+       decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;8"));
+       result = Check(testName, 8, decision, false, defaultDomain, "No trigger");
+       if (! result) goto cleanup;
+       
+       delete file;
+       return true;
+       
+cleanup:
+       if (decision != NULL)
+       {
+               cout << "========== Dumping incorrect decision ========== " << endl;
+               decision->Print();
+       }
+       delete file;
+       return false;
+}
+
+
+/// Routine for checking the result of the SymbolTestConfig() config in TriggerConfig.C
+bool CheckSymbolTestConfig(const char* testName = "Symbol config")
+{
+       AliHLTGlobalTriggerDecision* decision = NULL;
+       bool result = false;
+       
+       AliHLTTriggerDomain domainAll("*******:***,-DAQRDOUT:TST");
+       AliHLTTriggerDomain domainPHOS("CLUSTERS:PHOS,TRACKS:PHOS");
+       AliHLTTriggerDomain domainTPC("CLUSTERS:TPC ,TRACKS:TPC ");
+       domainTPC.Add(AliHLTReadoutList("TPC"));
+       AliHLTTriggerDomain domainMUON("TRACKS:MUON");
+       domainMUON.Add(AliHLTReadoutList("MUONTRK"));
+       domainMUON.Add(AliHLTReadoutList("MUONTRG"));
+       AliHLTTriggerDomain domainSSD("*******:SSD ");
+       domainSSD.Add(AliHLTReadoutList("ITSSSD"));
+
+       TFile* file = new TFile("testOutputFile.root", "READ");
+       
+       // Triggers in events (i.e. input triggers) and trigger classes in AliHLTEventSummary:
+       // event 1: TPC MUON SSD, 0x2
+       // event 2: TPC         , 0x2
+       // event 3: MUON        , 0x1
+       // event 4: SSD         , 0x2
+       // event 5: TPC MUON    , 0x1
+       // event 6: TPC SSD     , 0x2
+       // event 7: MUON SSD    , 0x1
+       // event 8: (empty)     , 0x0
+       decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;1"));
+       result = Check(testName, 1, decision, true, domainAll - AliHLTTriggerDomain("DAQRDOUT:EMC"), "Pass through");
+       if (! result) goto cleanup;
+       decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;2"));
+       result = Check(testName, 2, decision, true, domainTPC | domainPHOS, "Trigger class 2");
+       if (! result) goto cleanup;
+       decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;3"));
+       result = Check(testName, 3, decision, false, AliHLTTriggerDomain(), "");
+       if (! result) goto cleanup;
+       decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;4"));
+       result = Check(testName, 4, decision, true, domainPHOS, "Trigger class 2");
+       if (! result) goto cleanup;
+       decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;5"));
+       result = Check(testName, 5, decision, true, domainAll - AliHLTTriggerDomain("DAQRDOUT:EMC"), "Pass through");
+       if (! result) goto cleanup;
+       decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;6"));
+       result = Check(testName, 6, decision, true, domainTPC | domainPHOS, "Trigger class 2");
+       if (! result) goto cleanup;
+       decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;7"));
+       result = Check(testName, 7, decision, false, AliHLTTriggerDomain(), "");
+       if (! result) goto cleanup;
+       decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;8"));
+       result = Check(testName, 8, decision, false, AliHLTTriggerDomain(), "");
+       if (! result) goto cleanup;
+       
+       delete file;
+       return true;
+       
+cleanup:
+       if (decision != NULL)
+       {
+               cout << "========== Dumping incorrect decision ========== " << endl;
+               decision->Print();
+       }
+       delete file;
+       return false;
+}
+
+
+/// Routine for checking the result of the ComplexTestConfig() config in TriggerConfig.C
+bool CheckComplexTestConfig(const char* testName = "Complex config")
+{
+       AliHLTGlobalTriggerDecision* decision = NULL;
+       bool result = false;
+       
+       AliHLTTriggerDomain domainAll("*******:***,-DAQRDOUT:TST,-DAQRDOUT:EMC");
+       AliHLTTriggerDomain domainPHOS("CLUSTERS:PHOS,TRACKS:PHOS");
+       AliHLTTriggerDomain domainTPC("CLUSTERS:TPC ,TRACKS:TPC ");
+       domainTPC.Add(AliHLTReadoutList("TPC"));
+       AliHLTTriggerDomain domainMUON("TRACKS:MUON");
+       domainMUON.Add(AliHLTReadoutList("MUONTRK"));
+       domainMUON.Add(AliHLTReadoutList("MUONTRG"));
+       AliHLTTriggerDomain domainSSD("*******:SSD ");
+       domainSSD.Add(AliHLTReadoutList("ITSSSD"));
+
+       TFile* file = new TFile("testOutputFile.root", "READ");
+       
+       // Triggers in events (i.e. input triggers) and trigger classes in AliHLTEventSummary:
+       // event 1: TPC MUON SSD, 0x2
+       // event 2: TPC         , 0x2
+       // event 3: MUON        , 0x1
+       // event 4: SSD         , 0x2
+       // event 5: TPC MUON    , 0x1
+       // event 6: TPC SSD     , 0x2
+       // event 7: MUON SSD    , 0x1
+       // event 8: (empty)     , 0x0
+       decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;1"));
+       result = Check(testName, 1, decision, true, domainAll, "Pass through");
+       if (! result) goto cleanup;
+       decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;2"));
+       result = Check(testName, 2, decision, true, domainTPC, "Slow trigger");
+       if (! result) goto cleanup;
+       decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;3"));
+       result = Check(testName, 3, decision, true, domainMUON, "MUON trigger 2");
+       if (! result) goto cleanup;
+       decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;4"));
+       result = Check(testName, 4, decision, true, domainSSD | domainPHOS, "SSD trigger 2");
+       if (! result) goto cleanup;
+       decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;5"));
+       result = Check(testName, 5, decision, true, domainMUON, "MUON trigger 2");
+       if (! result) goto cleanup;
+       decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;6"));
+       result = Check(testName, 6, decision, true, domainSSD | domainPHOS, "SSD trigger 2");
+       if (! result) goto cleanup;
+       decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;7"));
+       result = Check(testName, 7, decision, true, domainSSD | domainMUON, "SSD trigger 1,MUON trigger 1");
+       if (! result) goto cleanup;
+       decision = dynamic_cast<AliHLTGlobalTriggerDecision*>(file->Get("HLTGlobalTrigger;8"));
+       result = Check(testName, 8, decision, true, domainAll, "Pass through");
+       if (! result) goto cleanup;
+       
+       delete file;
+       return true;
+       
+cleanup:
+       if (decision != NULL)
+       {
+               cout << "========== Dumping incorrect decision ========== " << endl;
+               decision->Print();
+       }
+       delete file;
+       return false;
+}
+
+
 typedef bool (*CheckFunctionType)(const char* testName);
 
 /**
@@ -361,30 +628,39 @@ typedef bool (*CheckFunctionType)(const char* testName);
  * \param testName  The name of the test being run.
  * \param numOfEvents  The number of events to run the chain for.
  * \param customClass  Name of the custom class as passed to <i>RunTrigger</i>.
+ * \param showOutput  If true then the output from the RunTrigger method is not suppressed.
  * \returns true if the different checks succeeded and false otherwise.
  */
-bool CheckDifferentModes(CheckFunctionType function, int version, const char* testName, int numOfEvents = 8, const char* customClass = NULL)
+bool CheckDifferentModes(
+               CheckFunctionType function, int version, const char* testName,
+               int numOfEvents = 8, const char* customClass = NULL,
+               bool showOutput = false
+       )
 {
        TString name = testName;
-       RunTrigger(version, false, false, numOfEvents, customClass);
+       name += " in debug mode";
+       cout << "#################### Running test: " << name.Data() << " ####################" << endl;
+       CallRunTrigger(version, false, true, numOfEvents, customClass, showOutput);
        if (! function(testName)) return false;
        gSystem->Exec("rm -f testOutputFile.root");  // Cleanup output file for next test.
        
        name = testName;
-       name += " interpreted with CINT";
-       RunTrigger(version, true, false, numOfEvents, customClass);
+       cout << "#################### Running test: " << name.Data() << " ####################" << endl;
+       CallRunTrigger(version, false, false, numOfEvents, customClass, showOutput);
        if (! function(testName)) return false;
        gSystem->Exec("rm -f testOutputFile.root");  // Cleanup output file for next test.
        
        name = testName;
-       name += " in debug mode";
-       RunTrigger(version, false, true, numOfEvents, customClass);
+       name += " interpreted with CINT in debug mode";
+       cout << "#################### Running test: " << name.Data() << " ####################" << endl;
+       CallRunTrigger(version, true, true, numOfEvents, customClass, showOutput);
        if (! function(testName)) return false;
        gSystem->Exec("rm -f testOutputFile.root");  // Cleanup output file for next test.
        
        name = testName;
-       name += " interpreted with CINT in debug mode";
-       RunTrigger(version, true, true, numOfEvents, customClass);
+       name += " interpreted with CINT";
+       cout << "#################### Running test: " << name.Data() << " ####################" << endl;
+       CallRunTrigger(version, true, false, numOfEvents, customClass, showOutput);
        if (! function(testName)) return false;
        gSystem->Exec("rm -f testOutputFile.root");  // Cleanup output file for next test.
        
@@ -395,16 +671,47 @@ bool CheckDifferentModes(CheckFunctionType function, int version, const char* te
  * Runs several tests for the AliHLTGlobalTriggerComponent class.
  * We specifically test if the global trigger menu configuration is interpreted
  * correctly and the trigger logic generated correctly on the fly.
- * \param numOfEvents  The number of events to run the chain for.
+ * \param configVersion  The appropriate version number of the config being tested
+ *     which is passed to TriggerConfig.C.
  * \param customClass  Name of the custom class as passed to <i>CheckDifferentModes</i>.
  * \returns true if the different checks succeeded and false otherwise.
+ * \param numOfEvents  The number of events to run the chain for.
+ * \returns true if all the tests succeeded and false otherwise.
  */
-bool testGlobalTriggerComponent(int numOfEvents = 8, const char* customClass = NULL)
+bool testGlobalTriggerComponent(int configVersion = -1, const char* customClass = NULL, int numOfEvents = 8)
 {
        GenerateInputData();
        
+       if (configVersion != -1)
+       {
+               CheckFunctionType function = NULL;
+               switch (configVersion)
+               {
+               case 0: function = CheckPriorityGroupTestConfig; break;
+               case 1: function = CheckSingleGroupTestConfig; break;
+               case 2: function = CheckPrescalarTestConfig; break;
+               case 3: function = CheckSymbolTestConfig; break;
+               case 4: function = CheckComplexTestConfig; break;
+               default:
+                       cerr << "ERROR: Invalid value for configVersion specified." << endl;
+                       return false;
+               }
+               bool result = CheckDifferentModes(
+                               function,
+                               configVersion,
+                               Form("Config version %d", configVersion),
+                               numOfEvents,
+                               customClass,
+                               true
+                       );
+               return result;
+       }
+       
        if (! CheckDifferentModes(CheckPriorityGroupTestConfig, 0, "Priority group config", numOfEvents, customClass)) return false;
        if (! CheckDifferentModes(CheckSingleGroupTestConfig, 1, "Single group config", numOfEvents, customClass)) return false;
+       if (! CheckDifferentModes(CheckPrescalarTestConfig, 2, "Prescalar config", numOfEvents, customClass)) return false;
+       if (! CheckDifferentModes(CheckSymbolTestConfig, 3, "Symbol config", numOfEvents, customClass)) return false;
+       if (! CheckDifferentModes(CheckComplexTestConfig, 4, "Complex config", numOfEvents, customClass)) return false;
        
        // Cleanup all temporary files generated.
        gSystem->Exec("rm -f testOutputFile.root testInputFile*.root AliHLTGlobalTriggerImpl*");
@@ -412,14 +719,18 @@ bool testGlobalTriggerComponent(int numOfEvents = 8, const char* customClass = N
 }
 
 
-
 #ifndef __MAKECINT__
 
 int main(int /*argc*/, const char** /*argv*/)
 {
-       gSystem->Exec("if test ! -f TriggerConfig.C ; then cp $ALICE_ROOT/HLT/trigger/test/TriggerConfig.C ./; fi");
+       const char* cpCmd1 = "if test ! -f TriggerConfig.C ; then cp $ALICE_ROOT/HLT/trigger/test/TriggerConfig.C ./; exit 1; fi";
+       const char* cpCmd2 = "if test ! -f testGlobalTriggerComponent.C ; then cp $ALICE_ROOT/HLT/trigger/test/testGlobalTriggerComponent.C ./; exit 1; fi";
+       bool copiedFile1 = gSystem->Exec(cpCmd1) != 0;
+       bool copiedFile2 = gSystem->Exec(cpCmd2) != 0;
        bool resultOk = testGlobalTriggerComponent();
        if (not resultOk) return 1;
+       if (copiedFile1) gSystem->Exec("rm TriggerConfig.C");
+       if (copiedFile2) gSystem->Exec("rm testGlobalTriggerComponent.C");
        return 0;
 }