]> git.uio.no Git - u/mrichter/AliRoot.git/commitdiff
Adding trigger counters class derived from AliHLTScalars, which will be used to store...
authoraszostak <aszostak@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 28 Oct 2010 23:06:20 +0000 (23:06 +0000)
committeraszostak <aszostak@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 28 Oct 2010 23:06:20 +0000 (23:06 +0000)
HLT/libAliHLTTrigger.pkg
HLT/trigger/AliHLTTriggerCounters.cxx [new file with mode: 0644]
HLT/trigger/AliHLTTriggerCounters.h [new file with mode: 0644]
HLT/trigger/AliHLTTriggerLinkDef.h
HLT/trigger/test/Makefile.am
HLT/trigger/test/testAliHLTTriggerCounters.C [new file with mode: 0644]

index 8245b939984b6971e270f10f55a6efb8bd60ec6a..161d92ccc8caf2295f3939bb6c923cedbbd50ca6 100644 (file)
@@ -36,7 +36,8 @@ CLASS_HDRS:= \
                AliHLTTriggerGammaConversion.h              \
                AliHLTMuonSpectroScalars.h                  \
                AliHLTMuonSpectroTriggerComponent.h         \
-               AliHLTUpcTriggerComponent.h
+               AliHLTUpcTriggerComponent.h                 \
+               AliHLTTriggerCounters.h
 
 # library sources
 MODULE_SRCS:=  $(CLASS_HDRS:.h=.cxx)
diff --git a/HLT/trigger/AliHLTTriggerCounters.cxx b/HLT/trigger/AliHLTTriggerCounters.cxx
new file mode 100644 (file)
index 0000000..0b57c7d
--- /dev/null
@@ -0,0 +1,208 @@
+// $Id: $
+/**************************************************************************
+ * This file is property of and copyright by the ALICE HLT Project        *
+ * All rights reserved.                                                   *
+ *                                                                        *
+ * Primary Authors:                                                       *
+ *   Artur Szostak <artursz@iafrica.com>                                  *
+ *                                                                        *
+ * 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   AliHLTTriggerCounters.cxx
+///  @author Artur Szostak <artursz@iafrica.com>
+///  @date   4 Sep 2010
+///  @brief  Implementation of the HLT global trigger counters.
+///
+/// This implements the trigger counters for the global HLT.
+/// These contain the total number of fired triggers by class and their current
+/// estimated rate.
+
+#include "AliHLTTriggerCounters.h"
+#include "TString.h"
+#include "AliLog.h"
+#include "TIterator.h"
+#include "Riostream.h"
+#include <cassert>
+
+ClassImp(AliHLTTriggerCounters);
+ClassImp(AliHLTTriggerCounters::AliCounter);
+
+
+AliHLTTriggerCounters::AliHLTTriggerCounters() :
+       AliHLTScalars(AliHLTTriggerCounters::AliCounter::Class(), 128),
+       fTimeStamp()
+{
+       // Default constructor.
+}
+
+
+AliHLTTriggerCounters::AliHLTTriggerCounters(const AliHLTTriggerCounters& obj) :
+       AliHLTScalars(obj),
+       fTimeStamp(obj.fTimeStamp)
+{
+       // Copy constructor performs a deep copy.
+}
+
+
+AliHLTTriggerCounters::~AliHLTTriggerCounters()
+{
+       // Default destructor.
+}
+
+AliHLTScalars::AliScalar* AliHLTTriggerCounters::NewScalar(UInt_t i, const char* name, const char* description, Double_t value)
+{
+       // Creates a new scalar object.
+       
+       return new (ScalarForConstructor(i)) AliCounter(name, description, 0, value);
+}
+
+
+const AliHLTScalars::AliScalar& AliHLTTriggerCounters::Sentinel() const
+{
+       // Returns an empty sentinel object.
+       
+       static AliHLTTriggerCounters::AliCounter sentinel;
+       return sentinel;
+}
+
+
+bool AliHLTTriggerCounters::Add(const char* name, const char* description, Double_t rate, ULong64_t value)
+{
+       // Adds a new counter.
+
+       AliScalar* scalar = NULL;
+       bool exists = AliHLTScalars::Add(scalar, name, description, rate);
+       assert(scalar != NULL);
+       static_cast<AliCounter*>(scalar)->Counter(value);
+       return exists;
+}
+
+void AliHLTTriggerCounters::Reset()
+{
+       // Sets all the counter values and rates to zero.
+       
+       for (UInt_t i = 0; i < NumberOfCounters(); ++i)
+       {
+               AliCounter* counter = static_cast<AliCounter*>( ScalarUncheckedAt(i) );
+               counter->Counter(0);
+               counter->Rate(0);
+       }
+}
+
+
+void AliHLTTriggerCounters::Copy(TObject& object) const
+{
+       // Performs a deep copy.
+       
+       if (object.IsA() != AliHLTTriggerCounters::Class())
+       {
+               AliError(Form("Cannot copy to an object of type '%s'.", object.ClassName()));
+               return;
+       }
+       AliHLTTriggerCounters* obj = static_cast<AliHLTTriggerCounters*>(&object);
+       obj->operator = (*this);
+}
+
+
+void AliHLTTriggerCounters::Print(Option_t* option) const
+{
+       // Prints the HLT trigger counters.
+
+       TString opt = option;
+       if (opt == "compact")
+       {
+               if (NumberOfCounters() > 0)
+               {
+                       AliCounter* counter = static_cast<AliCounter*>( ScalarUncheckedAt(0) );
+                       cout << counter->Counter();
+               }
+               for (UInt_t i = 1; i < NumberOfCounters(); ++i)
+               {
+                       AliCounter* counter = static_cast<AliCounter*>( ScalarUncheckedAt(i) );
+                       cout << ", " << counter->Counter();
+               }
+               cout << endl;
+               return;
+       }
+       
+       // Calculate the maximum field width required to keep things aligned.
+       int fieldwidth = 0;
+       for (UInt_t i = 0; i < NumberOfCounters(); ++i)
+       {
+               AliCounter* counter = static_cast<AliCounter*>( ScalarUncheckedAt(i) );
+               int length = strlen(counter->Name()) + strlen(counter->Description()) + 3;
+               if (length > fieldwidth) fieldwidth = length;
+       }
+       if (fieldwidth > 80) fieldwidth = 80;
+       
+       cout << "HLT trigger counters (" << fTimeStamp.AsString() << "):" << endl;
+       for (UInt_t i = 0; i < NumberOfCounters(); ++i)
+       {
+               AliCounter* counter = static_cast<AliCounter*>( ScalarUncheckedAt(i) );
+               TString str = counter->Description();
+               str += " (";
+               str += counter->Name();
+               str += ")";
+               cout << setw(fieldwidth) << str.Data() << setw(0)
+                    << " = " << counter->Counter() << setw(0)
+                    << " (" << counter->Rate() << " Hz)"
+                    << endl;
+       }
+       if (NumberOfCounters() == 0) cout << "(none)" << endl;
+}
+
+
+AliHLTTriggerCounters& AliHLTTriggerCounters::operator = (const AliHLTTriggerCounters& obj)
+{
+       // Performs a deep copy.
+       
+       if (this == &obj) return *this;
+       Clear();  // Remove existing counters.
+       TObject::operator = (obj);
+       fTimeStamp = obj.fTimeStamp;
+       for (UInt_t i = 0; i < obj.NumberOfCounters(); ++i)
+       {
+               AliCounter* counter = static_cast<AliCounter*>( obj.ScalarUncheckedAt(i) );
+               Add(counter->Name(), counter->Description(), counter->Rate(), counter->Counter());
+       }
+       return *this;
+}
+
+
+bool AliHLTTriggerCounters::operator == (const AliHLTTriggerCounters& obj) const
+{
+       // Compares two counter lists to see that they have the same counter values.
+
+       if (NumberOfCounters() != obj.NumberOfCounters()) return false;
+       if (fTimeStamp != obj.fTimeStamp) return false;
+       
+       for (UInt_t i = 0; i < NumberOfCounters(); ++i)
+       {
+               const AliCounter* a = static_cast<const AliCounter*>( ScalarUncheckedAt(i) );
+               const AliCounter* b = static_cast<const AliCounter*>( obj.FindObject(a->Name()) );
+               if (b == NULL) return false;
+               if (a->Value() != b->Value() or a->Rate() != b->Rate()) return false;
+       }
+       return true;
+}
+
+
+void AliHLTTriggerCounters::AliCounter::Copy(TObject& object) const
+{
+       // Performs a deep copy.
+       
+       if (object.IsA() != AliHLTTriggerCounters::AliCounter::Class())
+       {
+               AliError(Form("Cannot copy to an object of type '%s'.", object.ClassName()));
+               return;
+       }
+       AliHLTTriggerCounters::AliCounter* obj = static_cast<AliHLTTriggerCounters::AliCounter*>(&object);
+       *obj = *this;
+}
diff --git a/HLT/trigger/AliHLTTriggerCounters.h b/HLT/trigger/AliHLTTriggerCounters.h
new file mode 100644 (file)
index 0000000..d205c2b
--- /dev/null
@@ -0,0 +1,225 @@
+//-*- Mode: C++ -*-
+// $Id: $
+#ifndef AliHLTTRIGGERCOUNTERS_H
+#define AliHLTTRIGGERCOUNTERS_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   AliHLTTriggerCounters.h
+///  @author Artur Szostak <artursz@iafrica.com>
+///  @date   4 Sep 2010
+///  @brief  Declares the global trigger counters class for the HLT.
+
+#include "AliHLTScalars.h"
+#include "TNamed.h"
+#include "TTimeStamp.h"
+#include "TClonesArray.h"
+#include "THashTable.h"
+
+/**
+ * @class AliHLTTriggerCounters
+ * @brief HLT global trigger counters.
+ *
+ * This counters class contains summary information about the number of times a
+ * trigger was fired in the HLT and its current rate estimate. Objects of this
+ * class are generated by the AliHLTTriggerCountersMakerComponent to be used for
+ * monitoring purposes.
+ *
+ * \ingroup alihlt_trigger_components
+ */
+class AliHLTTriggerCounters : public AliHLTScalars
+{
+public:
+       /**
+        * This class stores all the required information for a HLT global trigger counter.
+        */
+       class AliCounter : public AliHLTScalars::AliScalar
+       {
+       public:
+               /// Default constructor
+               AliCounter() : AliHLTScalars::AliScalar(), fCounter(0) {}
+               
+               /// Constructor to set some initial values.
+               AliCounter(const char* name, const char* description, ULong64_t value, Double_t rate) :
+                       AliHLTScalars::AliScalar(name, description, rate), fCounter(value)
+               {}
+               
+               /// Default destructor
+               virtual ~AliCounter() {}
+               
+               /// Resets the counter value.
+               virtual void Clear(Option_t* /*option*/ = "") { fCounter = 0; Rate(0); }
+       
+               /// Inherited from TObject. Performs a deep copy.
+               virtual void Copy(TObject& object) const;
+               
+               /// Returns the value of the counter.
+               ULong64_t Counter() const { return fCounter; }
+
+               /// Sets a new value for the counter.
+               void Counter(ULong64_t value) { fCounter = value; }
+
+               /**
+                * Increments the counter by a value of 'count'.
+                * \param count  The number to increment the counter by. The default is 1.
+                * \note The rate is not updated.
+                */
+               void Increment(UInt_t count = 1) { fCounter += count; }
+
+               /// Returns the rate of the counter (Hz).
+               Double_t Rate() const { return Value(); }
+               
+               /**
+                * Sets a new value for the counter's rate.
+                * \param value  The new value to use (Hz). If negative then 0 is used instead.
+                */
+               void Rate(Double_t value) { Value(value >= 0 ? value : 0); }
+               
+               /// Checks if two counter objects are identical.
+               bool operator == (const AliCounter& x) const
+               {
+                       return AliHLTScalars::AliScalar::operator == (x)
+                              and fCounter == x.fCounter;
+               }
+               
+               /// Checks if two counter objects are not identical.
+               bool operator != (const AliCounter& x) const
+               {
+                       return not (this->operator == (x));
+               }
+               
+       private:
+               ULong64_t fCounter; // The counter's value.
+               
+               ClassDef(AliCounter, 1);  // HLT trigger counter value.
+       };
+       
+       /// Default constructor.
+       AliHLTTriggerCounters();
+       
+       /// The copy constructor performs a deep copy.
+       AliHLTTriggerCounters(const AliHLTTriggerCounters& obj);
+       
+       /// Default destructor.
+       virtual ~AliHLTTriggerCounters();
+       
+       /**
+        * Adds a new counter to the end of the counters list.
+        * If the counter already exists then its values are updated instead.
+        * \param name  The name of the counter value.
+        * \param description  A short description of the counter value.
+        * \param rate  The rate of the new counter.
+        * \param value  The value of the new counter.
+        * \returns true if the counter already exists and false otherwise.
+        */
+       bool Add(const char* name, const char* description, Double_t rate, ULong64_t value);
+       
+       using AliHLTScalars::Add;
+
+       /**
+        * Fetches the specified counter object.
+        * \param name  The name of the counter object.
+        * \returns the found counter object, otherwise an empty sentinel object with
+        *    zeros. One can tell it is a sentinel because the name will be empty.
+        */
+       const AliCounter& GetCounter(const char* name) const { return static_cast<const AliCounter&>(GetScalar(name)); }
+
+       /**
+        * Fetches the specified counter object for editing.
+        * \param name  The name of the counter object.
+        * \returns the found counter object. If the counter does not already
+        *     exist then a new one is created and returned.
+        */
+       AliCounter& GetCounter(const char* name) { return static_cast<AliCounter&>(GetScalar(name)); }
+       
+       /// Returns the number of counter values.
+       UInt_t NumberOfCounters() const { return NumberOfScalars(); }
+
+       // Note: the following GetCounterN methods do not use the same name as
+       // GetCounter above because the parameter type would unfortunately be
+       // ambiguous to an ISO c++ compiler.
+       
+       /**
+        * Fetches the n'th counter object.
+        * \param n  The number of the counter object.
+        * \returns the found counter object, otherwise an empty sentinel object with
+        *    zeros. One can tell it is a sentinel because the name will be empty.
+        */
+       const AliCounter& GetCounterN(UInt_t n) const { return static_cast<const AliCounter&>(GetScalarN(n)); }
+
+       /**
+        * Fetches the n'th counter object for editing.
+        * \param n  The number of the counter object.
+        * \returns the found counter object. If the counter does not already
+        *     exist then a new one is created and returned.
+        */
+       AliCounter& GetCounterN(UInt_t n) { return static_cast<AliCounter&>(GetScalarN(n)); }
+
+       /// Returns the timestamp for the counters.
+       const TTimeStamp& TimeStamp() const { return fTimeStamp; }
+
+       /// Updates the timestamp to the current time.
+       void UpdateTimeStamp() { fTimeStamp = TTimeStamp(); }
+       
+       /// Resets all counter values and rates to zero.
+       virtual void Reset();
+       
+       /// Inherited form TObject. Performs a deep copy.
+       virtual void Copy(TObject& object) const;
+       
+       /**
+        * Inherited from TObject, this prints the contents of this summary object.
+        * \param option  Can be "compact", which will just print all the values on one line.
+        */
+       virtual void Print(Option_t* option = "") const;
+       
+       /**
+        * The assignment operator performs a deep copy.
+        */
+       AliHLTTriggerCounters& operator = (const AliHLTTriggerCounters& obj);
+       
+       /// Returns the n'th counter or a zero sentinel if n is out of range.
+       const AliCounter& operator [] (UInt_t n) const { return GetCounterN(n); }
+
+       /// Returns the n'th counter for editing. A new counter is created if n is out of range.
+       AliCounter& operator [] (UInt_t n) { return GetCounterN(n); }
+
+       /// Returns the named counter or a zero sentinel if no such counter is found.
+       const AliCounter& operator [] (const char* name) const { return GetCounter(name); }
+
+       /// Returns the named counter for editing. A new counter is created if n is out of range.
+       AliCounter& operator [] (const char* name) { return GetCounter(name); }
+       
+       /**
+        * Comparison operator to check if two sets of counters have the same values
+        * and time stamp.
+        * \note The description strings are not checked so they could be different
+        *   and the order of the counters does not matter either.
+        */
+       bool operator == (const AliHLTTriggerCounters& obj) const;
+       
+       /**
+        * Comparison operator to check if two sets of counters are different.
+        * \note The description strings are not checked, only the values and rates are.
+        *   In addition, the order of the counters does not matter.
+        */
+       bool operator != (const AliHLTTriggerCounters& obj) const
+       {
+               return not (this->operator == (obj));
+       }
+
+protected:
+       
+       // The following is inherited from AliHLTScalars:
+       virtual AliScalar* NewScalar(UInt_t i, const char* name, const char* description, Double_t value);
+       virtual const AliScalar& Sentinel() const;
+       
+private:
+       
+       TTimeStamp fTimeStamp;   // The time stamp for the counters.
+       
+       ClassDef(AliHLTTriggerCounters, 1);  // Set of HLT global trigger counters.
+};
+
+#endif // AliHLTTRIGGERCOUNTERS_H
index def6da2f3ec0dc4bd10123b14b2d585d41fcc96a..c5465919f63618d02ef704e2edd236671e632861 100644 (file)
@@ -32,4 +32,7 @@
 #pragma link C++ class AliHLTMuonSpectroScalars::AliScalar+;
 #pragma link C++ class AliHLTMuonSpectroTriggerComponent+;
 #pragma link C++ class AliHLTUpcTriggerComponent+;
+#pragma link C++ class AliHLTTriggerCounters+;
+#pragma link C++ class AliHLTTriggerCounters::AliCounter+;
+
 #endif
index 4479e204e6632e54d9fa1cdac33efb90307a8eac..1c7c1603b66b28571f4834c8b1263b5f564a2b60 100644 (file)
@@ -8,7 +8,7 @@ AM_CPPFLAGS                     = -I$(top_srcdir)/BASE \
 
 EXTRA_DIST                     = 
 
-check_PROGRAMS                 = testTriggerDomain testGlobalTriggerComponent testMuonSpectroTrigger
+check_PROGRAMS                 = testTriggerDomain testGlobalTriggerComponent testMuonSpectroTrigger testAliHLTTriggerCounters
 
 testTriggerDomain_SOURCES      = testTriggerDomain.C
 
@@ -16,6 +16,8 @@ testGlobalTriggerComponent_SOURCES    = testGlobalTriggerComponent.C
 
 testMuonSpectroTrigger_SOURCES = testMuonSpectroTrigger.C
 
+testAliHLTTriggerCounters_SOURCES = testAliHLTTriggerCounters.C
+
 # linker flags
 LDADD_COMMON                   = $(top_builddir)/BASE/libHLTbase.la \
                                  $(top_builddir)/MUON/libAliHLTMUON.la \
@@ -37,5 +39,8 @@ testMuonSpectroTrigger_LDADD  = $(LDADD_COMMON)
 
 testMuonSpectroTrigger_LDFLAGS = $(LDFLAGS_COMMON)
 
+testAliHLTTriggerCounters_LDADD   = $(LDADD_COMMON)
+testAliHLTTriggerCounters_LDFLAGS = $(LDFLAGS_COMMON)
+
 TESTS                          = $(check_PROGRAMS)
 
diff --git a/HLT/trigger/test/testAliHLTTriggerCounters.C b/HLT/trigger/test/testAliHLTTriggerCounters.C
new file mode 100644 (file)
index 0000000..c56d82c
--- /dev/null
@@ -0,0 +1,283 @@
+// $Id: $
+
+/**************************************************************************
+ * This file is property of and copyright by the ALICE HLT Project        *
+ * ALICE Experiment at CERN, All rights reserved.                         *
+ *                                                                        *
+ * Primary Authors: Artur Szostak <artursz@iafrica.com>                   *
+ *                  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   testAliHLTTriggerCounters.C
+/// @author Artur Szostak <artursz@iafrica.com>
+/// @date   28 Oct 2010
+/// @brief  Test program for the AliHLTTriggerCounters class.
+///
+
+#if !defined(__CINT__) || defined(__MAKECINT__)
+#include "AliHLTTriggerCounters.h"
+#include "TObjArray.h"
+#include "TString.h"
+#include "Riostream.h"
+#endif
+
+/**
+ * Tests basic functionality of the AliHLTTriggerCounters::AliCounter class.
+ */
+bool CheckCounterItemClass()
+{
+       AliHLTTriggerCounters::AliCounter s1("s1", "counter one", 1, 0.1);
+       AliHLTTriggerCounters::AliCounter s2("s2", "counter two", 2, 0.2);
+       AliHLTTriggerCounters::AliCounter s3("s2", "counter two", 3, 0.2);
+       if (TString(s1.GetName()) != s1.Name())
+       {
+               cerr << "ERROR: AliHLTTriggerCounters::AliCounter::GetName() returns a different value than AliHLTTriggerCounters::AliCounter::Name()." << endl;
+               return false;
+       }
+       if (TString(s1.GetTitle()) != s1.Description())
+       {
+               cerr << "ERROR: AliHLTTriggerCounters::AliCounter::GetTitle() returns a different value than AliHLTTriggerCounters::AliCounter::Description()." << endl;
+               return false;
+       }
+       if (s2 == s3)
+       {
+               cerr << "ERROR: equals operator for AliHLTTriggerCounters::AliCounter returns the wrong value." << endl;
+               return false;
+       }
+       if (! s2.IsEqual(&s3))
+       {
+               cerr << "ERROR: AliHLTTriggerCounters::AliCounter::IsEqual returns the wrong value." << endl;
+               return false;
+       }
+       s2.Increment();
+       if (! (s2 == s3))
+       {
+               cerr << "ERROR: equals operator for AliHLTTriggerCounters::AliCounter returns the wrong value." << endl;
+               return false;
+       }
+       TObjArray list;
+       list.Add(&s2);
+       list.Add(&s1);
+       list.Sort();
+       if (TString(list.At(0)->GetName()) != "s1")
+       {
+               cerr << "ERROR: Sorting objects of type AliHLTTriggerCounters::AliCounter is not working correctly." << endl;
+               return false;
+       }
+       return true;
+}
+
+/**
+ * Tests functionality of the AliHLTTriggerCounters class.
+ */
+bool CheckCountersListClass()
+{
+       AliHLTTriggerCounters s;
+       s.Add("a", "one", 1);
+       s.Add("b", "two", 2, 5);
+       if (s.NumberOfScalars() != 2)
+       {
+               cerr << "ERROR: The number of added counters is wrong for class AliHLTTriggerCounters." << endl;
+               return false;
+       }
+       if (! s.Exists("a"))
+       {
+               cerr << "ERROR: AliHLTTriggerCounters claims counter 'a' does not exist event though it was added." << endl;
+               return false;
+       }
+       if (! s.Exists("b"))
+       {
+               cerr << "ERROR: AliHLTTriggerCounters claims counter 'b' does not exist event though it was added." << endl;
+               return false;
+       }
+       s.Remove("a");
+       if (s.Exists("a"))
+       {
+               cerr << "ERROR: AliHLTTriggerCounters claims counter 'a' does not exist event though it was removed." << endl;
+               return false;
+       }
+       s.Add("a", "one", 1);
+       const AliHLTTriggerCounters& p = s;
+       if (p.GetCounter("a").Rate() != 1)
+       {
+               cerr << "ERROR: Constant version of AliHLTTriggerCounters::GetCounter(\"a\") returns the wrong counter object." << endl;
+               return false;
+       }
+       if (TString(p.GetCounter("c").Name()) != "" || TString(p.GetCounter("c").Description()) != "" || p.GetCounter("c").Rate() != 0 || p.GetCounter("c").Counter() != 0)
+       {
+               cerr << "ERROR: Constant version of AliHLTTriggerCounters::GetCounter(\"c\") does not return a sentinel object." << endl;
+               return false;
+       }
+       if (s.GetCounter("a").Rate() != 1)
+       {
+               cerr << "ERROR: AliHLTTriggerCounters::GetCounter(\"a\") returns the wrong counter object." << endl;
+               return false;
+       }
+       s.GetCounter("c").Value(3);
+       if (TString(s.GetCounter("c").Name()) != "c" || TString(s.GetCounter("c").Description()) != "")
+       {
+               cerr << "ERROR: AliHLTTriggerCounters::GetCounter(\"c\") does not create a new object." << endl;
+               return false;
+       }
+       s.Add("c", "three", 33, 7);
+       if (s.GetCounter("c").Rate() != 33 || s.GetCounter("c").Counter() != 7 || TString(s.GetCounter("c").Description()) != "")
+       {
+               cerr << "ERROR: AliHLTTriggerCounters::Add did not update an exisiting counter correctly." << endl;
+               return false;
+       }
+       if (TString(p.GetCounterN(0).Name()) != "b" || TString(p.GetCounterN(1).Name()) != "a" || TString(p.GetCounterN(2).Name()) != "c")
+       {
+               cerr << "ERROR: Constant version of AliHLTTriggerCounters::GetCounterN(0) returns the wrong counter object." << endl;
+               return false;
+       }
+       if (TString(s.GetCounterN(0).Name()) != "b" || TString(s.GetCounterN(1).Name()) != "a" || TString(s.GetCounterN(2).Name()) != "c")
+       {
+               cerr << "ERROR: AliHLTTriggerCounters::GetCounterN(0) returns the wrong counter object." << endl;
+               return false;
+       }
+       if (TString(p.GetCounterN(4).Name()) != "" || TString(p.GetCounterN(4).Description()) != "" || p.GetCounterN(4).Rate() != 0)
+       {
+               cerr << "ERROR: Constant version of AliHLTTriggerCounters::GetCounterN(4) returns the wrong counter object." << endl;
+               return false;
+       }
+       s.GetCounterN(4).Value(5);
+       if (TString(s.GetCounterN(4).Name()) != "Scalar4" || TString(s.GetCounterN(4).Description()) != "" || s.GetCounterN(4).Rate() != 5)
+       {
+               cerr << "ERROR: AliHLTTriggerCounters::GetCounterN(4) does not create a new counter object correctly." << endl;
+               return false;
+       }
+       if (TString(p.GetCounterN(3).Name()) != "Scalar3" || TString(p.GetCounterN(3).Description()) != "" || p.GetCounterN(3).Rate() != 0)
+       {
+               cerr << "ERROR: AliHLTTriggerCounters::GetCounterN(4) did not initialise the third counter as expected." << endl;
+               return false;
+       }
+       
+       // The following is a special check to check for compilation ambiguity
+       // rather than runtime behaviour.
+       if (s[4].Rate() != s["Scalar4"].Rate())
+       {
+               cerr << "ERROR: AliHLTTriggerCounters::operator[](UInt_t) did not return the same value as AliHLTTriggerCounters::operator[](const char*)." << endl;
+               return false;
+       }
+       
+       // Here we check to see that the AliHLTTriggerCounters::GetCounterN class correctly
+       // checks and finds an unused name.
+       s.Add("Scalar7", "six", 6, 2);
+       s.Add("Scalar7_0", "seven", 7, 3);
+       s.GetCounterN(7).Value(8);
+       if (! s.Exists("Scalar7_1") || s.GetCounterN(7).Rate() != 8 || s.GetCounter("Scalar7_1").Rate() != 8)
+       {
+               cerr << "ERROR: AliHLTTriggerCounters::GetCounterN is not creating a counter object with a unique name as expected." << endl;
+               return false;
+       }
+       
+       // Check the copying of the object.
+       AliHLTTriggerCounters* c1 = (AliHLTTriggerCounters*) s.Clone();
+       AliHLTTriggerCounters c2;
+       c2 = s;
+       AliHLTTriggerCounters c3;
+       s.Copy(c3);
+       if (! (*c1 == s) || *c1 != s)
+       {
+               cerr << "ERROR: The equals operator of AliHLTTriggerCounters is not working as expected." << endl;
+               return false;
+       }
+       if (c2 != s)
+       {
+               cerr << "ERROR: The assignment operator of AliHLTTriggerCounters is not working as expected." << endl;
+               return false;
+       }
+       if (c3 != s)
+       {
+               cerr << "ERROR: The method AliHLTTriggerCounters::Copy is not working as expected." << endl;
+               return false;
+       }
+       c1->UpdateTimeStamp();
+       if (*c1 == s)
+       {
+               cerr << "ERROR: Modification of the time stamp for AliHLTTriggerCounters did not work as expected or comparison operator is not working." << endl;
+               return false;
+       }
+       delete c1;
+       
+       // Now check the IsEqual and Reset methods:
+       if (! c2.IsEqual(&c3))
+       {
+               cerr << "ERROR: The AliHLTTriggerCounters::IsEqual method is not working as expected." << endl;
+               return false;
+       }
+       
+       c3.Reset();
+       for (UInt_t i = 0; i < c3.NumberOfScalars(); ++i)
+       {
+               if (c3[i].Rate() != 0 || c3[i].Counter() != 0)
+               {
+                       cerr << "ERROR: AliHLTTriggerCounters::Reset did not reset all counter values to zero." << endl;
+                       return false;
+               }
+               if (TString(c3[i].Name()) != c2[i].Name())
+               {
+                       cerr << "ERROR: AliHLTTriggerCounters::Reset modified the name by mistake." << endl;
+                       return false;
+               }
+               if (TString(c3[i].Description()) != c2[i].Description())
+               {
+                       cerr << "ERROR: AliHLTTriggerCounters::Reset modified the description by mistake." << endl;
+                       return false;
+               }
+       }
+       if (! c2.IsEqual(&c3))
+       {
+               cerr << "ERROR: The AliHLTTriggerCounters::IsEqual method is not working as expected after call to Reset." << endl;
+               return false;
+       }
+       if (c2 == c3)
+       {
+               cerr << "ERROR: The equals operator for AliHLTTriggerCounters is not working as expected after call to Reset." << endl;
+               return false;
+       }
+       
+       c2.Remove("c");
+       if (c2.IsEqual(&c3))
+       {
+               cerr << "ERROR: The AliHLTTriggerCounters::IsEqual method is not working as expected after call to Remove." << endl;
+               return false;
+       }
+       if (c2 == c3)
+       {
+               cerr << "ERROR: The equals operator for AliHLTTriggerCounters is not working as expected after call to Remove." << endl;
+               return false;
+       }
+       
+       return true;
+}
+
+/**
+ * Runs the unit test for the AliHLTTriggerCounters class.
+ * \returns true if the class passed the test and false otherwise.
+ */
+bool testAliHLTTriggerCounters()
+{
+       if (! CheckCounterItemClass()) return false;
+       if (! CheckCountersListClass()) return false;
+       return true;
+}
+
+#ifndef __MAKECINT__
+
+int main(int /*argc*/, const char** /*argv*/)
+{
+       bool resultOk = testAliHLTTriggerCounters();
+       if (not resultOk) return 1;
+       return 0;
+}
+
+#endif // __MAKECINT__