From 742ae1c405bcc9caef2e2ba65b67ce410f7a7362 Mon Sep 17 00:00:00 2001 From: aszostak Date: Fri, 12 Nov 2010 01:02:55 +0000 Subject: [PATCH] Adding trigger counting component. --- HLT/BASE/AliHLTDataTypes.cxx | 12 +- HLT/BASE/AliHLTDataTypes.h | 32 +- HLT/libAliHLTTrigger.pkg | 1 + HLT/trigger/AliHLTTriggerAgent.cxx | 2 + HLT/trigger/AliHLTTriggerCounterComponent.cxx | 474 ++++++++++++++++++ HLT/trigger/AliHLTTriggerCounterComponent.h | 200 ++++++++ HLT/trigger/AliHLTTriggerLinkDef.h | 1 + HLT/trigger/test/InitialCounterConfig.C | 33 ++ HLT/trigger/test/Makefile.am | 7 +- .../test/testTriggerCounterComponent.C | 408 +++++++++++++++ 10 files changed, 1155 insertions(+), 15 deletions(-) create mode 100644 HLT/trigger/AliHLTTriggerCounterComponent.cxx create mode 100644 HLT/trigger/AliHLTTriggerCounterComponent.h create mode 100644 HLT/trigger/test/InitialCounterConfig.C create mode 100644 HLT/trigger/test/testTriggerCounterComponent.C diff --git a/HLT/BASE/AliHLTDataTypes.cxx b/HLT/BASE/AliHLTDataTypes.cxx index 3127ababbec..44e159d61d9 100644 --- a/HLT/BASE/AliHLTDataTypes.cxx +++ b/HLT/BASE/AliHLTDataTypes.cxx @@ -190,10 +190,6 @@ const AliHLTComponentDataType kAliHLTDataTypeHistogram = AliHLTComponentDataType const char kAliHLTTNtupleDataTypeIDstring[8] = kAliHLTTNtupleDataTypeID; const AliHLTComponentDataType kAliHLTDataTypeTNtuple = AliHLTComponentDataTypeInitializer(kAliHLTTNtupleDataTypeIDstring, kAliHLTDataOriginAny); -/** AliHLTTriggerCounters object */ -const char kAliHLTTriggerCountersDataTypeIDstring[8] = kAliHLTTriggerCountersDataTypeID; -const AliHLTComponentDataType kAliHLTDataTypeTriggerCounters = AliHLTComponentDataTypeInitializer(kAliHLTTriggerCountersDataTypeIDstring, kAliHLTDataOriginHLT); - /** Array of HLT Tracks (AliHLTTracksData) */ const char kAliHLTTrackDataTypeIDstring[8] = kAliHLTTrackDataTypeID; const AliHLTComponentDataType kAliHLTDataTypeTrack = AliHLTComponentDataTypeInitializer(kAliHLTTrackDataTypeIDstring, kAliHLTDataOriginAny); @@ -222,6 +218,14 @@ const AliHLTComponentDataType kAliHLTDataTypedEdx = AliHLTComponentDataTypeIniti /** Container of dNdPt */ const AliHLTComponentDataType kAliHLTDataTypedNdPt = AliHLTComponentDataTypeInitializer( "DNDPT ", kAliHLTDataOriginAny ); +/** Input trigger counters */ +const char kAliHLTInputTriggerCountersDataTypeIDstring[8] = kAliHLTInputTriggerCountersDataTypeID; +const AliHLTComponentDataType kAliHLTDataTypeInputTriggerCounters = AliHLTComponentDataTypeInitializer(kAliHLTInputTriggerCountersDataTypeIDstring, kAliHLTDataOriginHLT); + +/** Input trigger counters */ +const char kAliHLTOutputTriggerCountersDataTypeIDstring[8] = kAliHLTOutputTriggerCountersDataTypeID; +const AliHLTComponentDataType kAliHLTDataTypeOutputTriggerCounters = AliHLTComponentDataTypeInitializer(kAliHLTOutputTriggerCountersDataTypeIDstring, kAliHLTDataOriginHLT); + ////////////////////////////////////////////////////////////////////////// // // Data origin variables, to be used with the operator| diff --git a/HLT/BASE/AliHLTDataTypes.h b/HLT/BASE/AliHLTDataTypes.h index 6978ad23c55..18688a43236 100644 --- a/HLT/BASE/AliHLTDataTypes.h +++ b/HLT/BASE/AliHLTDataTypes.h @@ -66,8 +66,9 @@ * Adding data block type for ESD content * Adding data block type for forwarded component table blocks * Adding new event type for software triggers. + * 15 Modifying data block types for trigger counter blocks. */ -#define ALIHLT_DATA_TYPES_VERSION 14 +#define ALIHLT_DATA_TYPES_VERSION 15 ////////////////////////////////////////////////////////////////////////// // @@ -492,12 +493,6 @@ const int kAliHLTComponentDataTypefIDsize=8; */ #define kAliHLTTNtupleDataTypeID {'R','O','O','T','T','U','P','L'} -/** HLT trigger counters. - * - For the AliHLTTriggerCounters object. Normally with HLT as origin. - * @ingroup alihlt_component_datatypes - */ -# define kAliHLTTriggerCountersDataTypeID {'T','R','G','C','O','U','N','T'} - /** HLT Track * - Struct for Tracks based on AliExternalTrackParam * - varying origin @@ -535,6 +530,16 @@ const int kAliHLTComponentDataTypefIDsize=8; */ # define kAliHLTdNdPtDataTypeID {'D','N','D','P','T',' ',' ',' '} +/** Global input trigger counters data block type. + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTInputTriggerCountersDataTypeID {'I','N','T','R','G','C','N','T'} + +/** Global output trigger counters data block type. + * @ingroup alihlt_component_datatypes + */ +# define kAliHLTOutputTriggerCountersDataTypeID {'O','T','T','R','G','C','N','T'} + using namespace std; extern "C" { @@ -1166,10 +1171,17 @@ extern "C" { */ extern const AliHLTComponentDataType kAliHLTDataTypeTNtuple; // {ROOTTUPL,"***"} - /** AliHLTTriggerCounters object for HLT global trigger counters. + /** Global input trigger counters. + * - origin : kAliHLTDataOriginOut ( HLT ) * @ingroup alihlt_component_datatypes - */ - extern const AliHLTComponentDataType kAliHLTDataTypeTriggerCounters; // {TRGCOUNT,"HLT "} + */ + extern const AliHLTComponentDataType kAliHLTDataTypeInputTriggerCounters; // {INTRGCNT:HLT } + + /** Global output trigger counters. + * - origin : kAliHLTDataOriginOut ( HLT ) + * @ingroup alihlt_component_datatypes + */ + extern const AliHLTComponentDataType kAliHLTDataTypeOutputTriggerCounters; // {OTTRGCNT:HLT } /** General track array for the barrel tracks based on AliExternalTrackParam * Data format defined by AliHLTTracksData diff --git a/HLT/libAliHLTTrigger.pkg b/HLT/libAliHLTTrigger.pkg index 161d92ccc8c..993a8d7681f 100644 --- a/HLT/libAliHLTTrigger.pkg +++ b/HLT/libAliHLTTrigger.pkg @@ -37,6 +37,7 @@ CLASS_HDRS:= \ AliHLTMuonSpectroScalars.h \ AliHLTMuonSpectroTriggerComponent.h \ AliHLTUpcTriggerComponent.h \ + AliHLTTriggerCounterComponent.h \ AliHLTTriggerCounters.h # library sources diff --git a/HLT/trigger/AliHLTTriggerAgent.cxx b/HLT/trigger/AliHLTTriggerAgent.cxx index afd3d050c68..920e0df137c 100644 --- a/HLT/trigger/AliHLTTriggerAgent.cxx +++ b/HLT/trigger/AliHLTTriggerAgent.cxx @@ -50,6 +50,7 @@ #include "AliHLTTriggerGammaConversion.h" #include "AliHLTMuonSpectroTriggerComponent.h" #include "AliHLTUpcTriggerComponent.h" +#include "AliHLTTriggerCounterComponent.h" /** global instance for agent registration */ @@ -91,6 +92,7 @@ int AliHLTTriggerAgent::RegisterComponents(AliHLTComponentHandler* pHandler) con pHandler->AddComponent(new AliHLTTriggerGammaConversion); pHandler->AddComponent(new AliHLTMuonSpectroTriggerComponent); pHandler->AddComponent(new AliHLTUpcTriggerComponent); + pHandler->AddComponent(new AliHLTTriggerCounterComponent); return 0; } diff --git a/HLT/trigger/AliHLTTriggerCounterComponent.cxx b/HLT/trigger/AliHLTTriggerCounterComponent.cxx new file mode 100644 index 00000000000..8d26fbbbe44 --- /dev/null +++ b/HLT/trigger/AliHLTTriggerCounterComponent.cxx @@ -0,0 +1,474 @@ +// $Id: AliHLTTriggerCounterComponent.cxx 43071 2010-08-25 08:41:44Z richterm $ +/************************************************************************** + * This file is property of and copyright by the ALICE HLT Project * + * ALICE Experiment at CERN, All rights reserved. * + * * + * Primary Authors: Artur Szostak * + * 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 AliHLTTriggerCounterComponent.cxx +/// @author Artur Szostak +/// @date 3 Nov 2010 +/// @brief Implementation of the AliHLTTriggerCounterComponent class. +/// +/// The AliHLTTriggerCounterComponent is used to count HLT input and output +/// triggers based on the global trigger decisions coming from the global HLT +/// trigger component. + +#include "AliHLTTriggerCounterComponent.h" +#include "AliHLTTriggerDecision.h" +#include "AliHLTGlobalTriggerDecision.h" +#include "AliHLTTriggerCounters.h" +#include "AliHLTCTPData.h" +#include "AliCDBManager.h" +#include "AliCDBStorage.h" +#include "AliCDBEntry.h" +#include "TObjString.h" +#include "TROOT.h" +#include +#include + +ClassImp(AliHLTTriggerCounterComponent) + +const char* AliHLTTriggerCounterComponent::fgkConfigCDBPath = "HLT/ConfigHLT/HLTTriggerCounter"; +TMap AliHLTTriggerCounterComponent::fgInitialCounterConfig(TCollection::kInitHashTableCapacity, 2); + + +AliHLTTriggerCounterComponent::AliHLTTriggerCounterComponent() : + AliHLTProcessor(), + fOutputMultiplier(0), + fInputCounters(), + fOutputCounters(), + fInputTimes(TCollection::kInitHashTableCapacity, 2), + fOutputTimes(TCollection::kInitHashTableCapacity, 2), + fLastPublishTime(-1), + fPublishPeriod(-1) +{ + // Default constructor. + + fInputTimes.SetOwner(kTRUE); + fOutputTimes.SetOwner(kTRUE); +} + + +AliHLTTriggerCounterComponent::~AliHLTTriggerCounterComponent() +{ + // Default destructor. + +} + + +const char* AliHLTTriggerCounterComponent::GetComponentID() +{ + // Returns the component ID. + return "HLTTriggerCounter"; +} + + +void AliHLTTriggerCounterComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list) +{ + // Returns the list of input data types that are handled. + list.push_back(kAliHLTDataTypeGlobalTrigger); + list.push_back(kAliHLTDataTypeTriggerDecision); +} + + +AliHLTComponentDataType AliHLTTriggerCounterComponent::GetOutputDataType() +{ + // Returns kAliHLTMultipleDataType. + return kAliHLTMultipleDataType; +} + + +int AliHLTTriggerCounterComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& list) +{ + // Returns the list of output data block types generated. + list.push_back(kAliHLTDataTypeInputTriggerCounters); + list.push_back(kAliHLTDataTypeOutputTriggerCounters); + return int(list.size()); +} + + +void AliHLTTriggerCounterComponent::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier) +{ + // Returns the buffer size requirements. + constBase = 1024*16; + inputMultiplier = fOutputMultiplier; +} + + +AliHLTComponent* AliHLTTriggerCounterComponent::Spawn() +{ + // Creates a new instance of the component. + return new AliHLTTriggerCounterComponent; +} + + +Int_t AliHLTTriggerCounterComponent::DoInit(int argc, const char** argv) +{ + // Initialises the data checker component from the command line. + + HLTInfo("Starting HLT trigger counter component."); + + const char* configFileName = NULL; + fInputCounters.Clear(); + fOutputCounters.Clear(); + fInputTimes.Clear(); + fOutputTimes.Clear(); + fLastPublishTime = -1; + fPublishPeriod = -1; + bool loadCDBObject = true; + + for (int i = 0; i < argc; ++i) + { + if (strcmp(argv[i], "-config") == 0) + { + if (configFileName != NULL) + { + HLTWarning("The configuration macro was already specified." + " Will replace previous value given by -config." + ); + } + if (argc <= i+1) + { + HLTError("The configuration macro filename was not specified." ); + return -EINVAL; + } + configFileName = argv[i+1]; + i++; + continue; + } + + if (strcmp(argv[i], "-publishperiod") == 0) + { + if (fPublishPeriod != -1) + { + HLTWarning("The publish period was already specified." + " Will replace previous value given by -publishperiod." + ); + } + if (argc <= i+1) + { + HLTError("Publish period value was not specified for -publishperiod."); + return -EINVAL; + } + char* err = NULL; + errno = 0; + double tmpnum = strtod(argv[i+1], &err); + if (err == NULL or *err != '\0') + { + HLTError("Cannot convert '%s' to a floating point value.", argv[i+1]); + return false; + } + if (errno == ERANGE) + { + HLTError("The specified value '%s' is out of range.", argv[i+1]); + return false; + } + fPublishPeriod = (tmpnum < 0 ? -1 : tmpnum); + i++; + continue; + } + + if (strcmp(argv[i], "-skipcdb") == 0) + { + loadCDBObject = false; + continue; + } + + HLTError("Unknown option '%s'.", argv[i]); + return -EINVAL; + } // for loop + + if (configFileName != NULL) + { + int result = LoadConfigFromFile(configFileName); + if (result != 0) return result; + } + else if (loadCDBObject) + { + int result = LoadConfigFromCDB(fgkConfigCDBPath); + if (result != 0) return result; + } + + return 0; +} + + +Int_t AliHLTTriggerCounterComponent::DoDeinit() +{ + // Cleans up the component. + + HLTInfo("Stopping HLT trigger counter component."); + fInputCounters.Clear(); + fOutputCounters.Clear(); + fInputTimes.Clear(); + fOutputTimes.Clear(); + return 0; +} + + +int AliHLTTriggerCounterComponent::DoEvent(const AliHLTComponentEventData& /*evtData*/, AliHLTComponentTriggerData& /*trigData*/) +{ + // Finds the global trigger objects and adds the triggers to the counters. + + fInputCounters.UpdateTimeStamp(); + fOutputCounters.UpdateTimeStamp(); + Double_t inputTime = fInputCounters.TimeStamp().AsDouble(); + Double_t outputTime = fOutputCounters.TimeStamp().AsDouble(); + + const TObject* obj = GetFirstInputObject(kAliHLTDataTypeGlobalTrigger, "AliHLTGlobalTriggerDecision"); + while (obj != NULL) + { + const AliHLTGlobalTriggerDecision* decision = dynamic_cast(obj); + if (decision != NULL) + { + HLTDebug("Received trigger decision object of type AliHLTGlobalTriggerDecision."); + // Tokenise the global trigger description string which contains a + // list of the triggers that were fired and increment the corresponding + // counters. + TString names = decision->Description(); + Ssiz_t from = 0; + TString token; + while (names.Tokenize(token, from, ",")) + { + TObject* cntobj = fOutputCounters.FindObject(token.Data()); + if (cntobj != NULL) + { + AliHLTTriggerCounters::AliCounter* counter = static_cast(cntobj); + counter->Increment(); + UpdateCounterRate( + counter, + static_cast( fOutputTimes.FindObject(token.Data()) ), + outputTime + ); + } + else + { + fOutputCounters.Add(token.Data(), "New trigger output counter found during the run.", 1, 1); + fOutputTimes.Add(new AliRingBuffer(token.Data(), outputTime)); + } + } + + // Now add the CTP triggers. + const AliHLTCTPData* ctp = dynamic_cast( decision->InputObjects().FindObject("AliHLTCTPData") ); + if (ctp != NULL) + { + const TArrayL64& counters = ctp->Counters(); + for (Int_t i = 0; i < counters.GetSize(); ++i) + { + const char* ctpName = ctp->Name(i); + // Check if CTP counter is initialised and skip if not. + if (strcmp(ctpName, "AliHLTReadoutList") == 0 and counters[i] == 0) continue; + TObject* cntobj = fInputCounters.FindObject(ctpName); + if (cntobj != NULL) + { + AliHLTTriggerCounters::AliCounter* counter = static_cast(cntobj); + counter->Counter(counters[i]); + UpdateCounterRate( + counter, + static_cast( fInputTimes.FindObject(ctpName) ), + inputTime + ); + } + else + { + fInputCounters.Add( + ctpName, + "New CTP trigger input counter found during the run.", + Double_t(counters[i]), + counters[i] + ); + fInputTimes.Add(new AliRingBuffer(ctpName, inputTime)); + } + } + } + + // Add the list of input triggers. + for (Int_t i = 0; i < decision->NumberOfTriggerInputs(); ++i) + { + const AliHLTTriggerDecision* input = decision->TriggerInput(i); + if (input == NULL or not input->Result()) continue; + TObject* cntobj = fInputCounters.FindObject(input->Name()); + if (cntobj != NULL) + { + AliHLTTriggerCounters::AliCounter* counter = static_cast(cntobj); + counter->Increment(); + counter->SetBit(BIT(14), true); // mark counter as updated + UpdateCounterRate( + counter, + static_cast( fInputTimes.FindObject(input->Name()) ), + inputTime + ); + } + else + { + fInputCounters.Add(input->Name(), "New trigger input counter found during the run.", 1, 1); + fInputCounters.GetCounterN(fInputCounters.NumberOfCounters()-1).SetBit(BIT(14), true); // mark counter as updated + fInputTimes.Add(new AliRingBuffer(input->Name(), inputTime)); + } + } + } + obj = GetNextInputObject(); + } + + // Look for the individual trigger decision blocks to add if they are available. + obj = GetFirstInputObject(kAliHLTDataTypeTriggerDecision, "AliHLTTriggerDecision"); + while (obj != NULL) + { + const AliHLTTriggerDecision* decision = dynamic_cast(obj); + if (decision != NULL and decision->Result()) + { + HLTDebug("Received trigger decision object of type AliHLTTriggerDecision."); + TObject* cntobj = fInputCounters.FindObject(decision->Name()); + if (cntobj != NULL) + { + AliHLTTriggerCounters::AliCounter* counter = static_cast(cntobj); + if (not counter->TestBit(BIT(14))) // Only update if marked as not updated. + { + counter->Increment(); + UpdateCounterRate( + counter, + static_cast( fInputTimes.FindObject(decision->Name()) ), + inputTime + ); + } + } + else + { + fInputCounters.Add(decision->Name(), "New trigger input counter found during the run.", 1, 1); + fInputTimes.Add(new AliRingBuffer(decision->Name(), inputTime)); + } + } + obj = GetNextInputObject(); + } + // Reset bit 14 which is used temporarily to mark updated counters. + for (UInt_t i = 0; i < fInputCounters.NumberOfCounters(); ++i) + { + fInputCounters.GetCounterN(i).SetBit(BIT(14), false); + } + + Double_t now = TTimeStamp(); + if (fLastPublishTime == -1) fLastPublishTime = now; + if (now - fLastPublishTime > fPublishPeriod) + { + fLastPublishTime = now; + bool inputCountersNotPushed = PushBack(&fInputCounters, kAliHLTDataTypeInputTriggerCounters) != 0; + bool outputCountersNotPushed = PushBack(&fOutputCounters, kAliHLTDataTypeOutputTriggerCounters) != 0; + if (inputCountersNotPushed or outputCountersNotPushed) + { + fOutputMultiplier = (fOutputMultiplier == 0 ? 1 : fOutputMultiplier*2); + return -ENOSPC; + } + } + return 0; +} + + +void AliHLTTriggerCounterComponent::UpdateCounterRate( + AliHLTTriggerCounters::AliCounter* counter, AliRingBuffer* timeBuf, Double_t newTime + ) +{ + // Updates the counter's rate value. + + assert(timeBuf != NULL); + Double_t dt = newTime - timeBuf->OldestTime(); + Double_t rate = (dt != 0 ? (counter->Counter() - timeBuf->OldestCounter()) / dt : 0.); + counter->Rate(rate); + timeBuf->Increment(counter->Counter(), newTime); +} + + +int AliHLTTriggerCounterComponent::LoadConfigFromCDB(const char* cdbPath) +{ + // Loads the initial configuration of counters from the given CDB path. + + HLTDebug("Trying to load trigger menu from '%s'.", cdbPath); + + if (AliCDBManager::Instance() == NULL) + { + HLTError("CDB manager object not found."); + return -EIO; + } + AliCDBStorage* store = AliCDBManager::Instance()->GetDefaultStorage(); + if (store == NULL) + { + HLTError("Could not get the the default storage for the CDB."); + return -EIO; + } + Int_t version = store->GetLatestVersion(cdbPath, GetRunNo()); + if (version < 0) + { + HLTError("Could not find an entry in the CDB for \"%s\".", cdbPath); + return -EIO; + } + Int_t subVersion = store->GetLatestSubVersion(cdbPath, GetRunNo(), version); + AliCDBEntry* entry = AliCDBManager::Instance()->Get(cdbPath, GetRunNo(), version, subVersion); + if (entry == NULL) + { + HLTError("Could not get the CDB entry for \"%s\".", cdbPath); + return -EIO; + } + TObject* obj = entry->GetObject(); + if (obj == NULL) + { + HLTError("Configuration object for \"%s\" is missing.", cdbPath); + return -ENOENT; + } + if (obj->IsA() != TMap::Class()) + { + HLTError("Wrong type for configuration object in \"%s\". Found a %s but we expect a TMap.", + cdbPath, obj->ClassName() + ); + return -EPROTO; + } + TMap* counters = static_cast(obj); + SetInitialCounters(counters); + return 0; +} + + +int AliHLTTriggerCounterComponent::LoadConfigFromFile(const char* configFile) +{ + // Loads the initial configuration of counters from the given configuration file. + + TString cmd = ".x "; + cmd += configFile; + gROOT->ProcessLine(cmd); + SetInitialCounters(&fgInitialCounterConfig); + return 0; +} + + +void AliHLTTriggerCounterComponent::SetInitialCounters(const TMap* counters) +{ + // Sets the initial counter values from TMap objects containing name description pairs. + + Double_t now = TTimeStamp(); + TMapIter next(counters); + TObject* key = NULL; + while ((key = next()) != NULL) + { + TObject* value = counters->GetValue(key); + if (value == NULL) continue; + if (key->TestBit(BIT(14))) + { + fOutputCounters.Add(key->GetName(), value->GetName()); + fOutputTimes.Add(new AliRingBuffer(key->GetName(), now)); + } + else + { + fInputCounters.Add(key->GetName(), value->GetName()); + fInputTimes.Add(new AliRingBuffer(key->GetName(), now)); + } + } +} diff --git a/HLT/trigger/AliHLTTriggerCounterComponent.h b/HLT/trigger/AliHLTTriggerCounterComponent.h new file mode 100644 index 00000000000..8b405641c08 --- /dev/null +++ b/HLT/trigger/AliHLTTriggerCounterComponent.h @@ -0,0 +1,200 @@ +//-*- Mode: C++ -*- +// $Id: $ +#ifndef ALIHLTTRIGGERCOUNTERCOMPONENT_H +#define ALIHLTTRIGGERCOUNTERCOMPONENT_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 AliHLTTriggerCounterComponent.h +/// \author Artur Szostak +/// \date 3 Nov 2010 +/// \brief Declaration of the AliHLTTriggerCounterComponent component class. + +#include "AliHLTProcessor.h" +#include "AliHLTTriggerCounters.h" +#include "THashTable.h" +#include "TTimeStamp.h" +#include "TMap.h" + +/** + * \class AliHLTTriggerCounterComponent + * This component is used to calculate online the trigger counters and rates for + * output HLT and input CTP / HLT triggers. The component should be connected to + * all the global trigger component instances in the chain and there should be + * only one instance of AliHLTTriggerCounterComponent in the chain. If more instances + * of AliHLTTriggerCounterComponent exist in the chain then the statistics will not + * be calculated correctly. + * + *

General properties:

+ * + * Component ID: \b HLTTriggerCounter
+ * Library: \b libAliHLTTrigger.so
+ * Input Data Types: kAliHLTDataTypeGlobalTrigger | kAliHLTDataTypeTriggerDecision
+ * Output Data Types: kAliHLTDataTypeInputTriggerCounters | kAliHLTDataTypeOutputTriggerCounters
+ * + *

Mandatory arguments:

+ * None. + * + *

Optional arguments:

+ * \li -config filename
+ * Indicates the configuration macro file to use for the initial trigger counter lists. + * \li -publishperiod period
+ * Sets the period between publishing of the trigger counters in seconds. + * The default is to publish for every event. + * \li -skipcdb
+ * If specified then the initial counter configuration is not loaded from the CDB. + * + *

Configuration:

+ * Can only be configured with the command line arguments. + * + *

Default CDB entries:

+ * HLT/ConfigHLT/HLTTriggerCounter - Contains the initial counter configuration. + * + *

Performance:

+ * Can run over 2kHz in HLT online system. + * + *

Memory consumption:

+ * Negligible. + * + *

Output size:

+ * Same order of magnitude as the input data size. + * + * \ingroup alihlt_tpc_components + */ +class AliHLTTriggerCounterComponent : public AliHLTProcessor +{ +public: + + AliHLTTriggerCounterComponent(); + virtual ~AliHLTTriggerCounterComponent(); + + // Methods inherited from AliHLTComponent: + virtual const char* GetComponentID(); + virtual void GetInputDataTypes(AliHLTComponentDataTypeList& list); + virtual AliHLTComponentDataType GetOutputDataType(); + virtual int GetOutputDataTypes(AliHLTComponentDataTypeList& list); + virtual void GetOutputDataSize(unsigned long& constBase, double& inputMultiplier); + virtual AliHLTComponent* Spawn(); + virtual Int_t DoInit(int argc, const char** argv); + virtual Int_t DoDeinit(); + + /** + * Returns a reference to the initial counter configuration to use. + * This should be used in the configuration file passed to the component with + * the -config option to setup the initial counter configuration. The following + * is an example of such a config file. + * \code + * void SetupConfig() { + * TMap& counters = AliHLTTriggerCounterComponent::InitialCounterConfig(); + * counters.Add(new TObjString("TRIGGER-A"), new TObjString("Some input trigger")); + * TObjString* outname = new TObjString("TRIGGER-B"); + * outname->SetBit(1<<14); + * counters.Add(outname, new TObjString("Some output trigger")); + * } + * \endcode + */ + static TMap& InitialCounterConfig() + { + fgInitialCounterConfig.SetOwner(kTRUE); // Make sure its the owner of all objects. + return fgInitialCounterConfig; + } + +protected: + + // Method inherited from AliHLTProcessor: + virtual int DoEvent(const AliHLTComponentEventData& evtData, AliHLTComponentTriggerData& trigData); + using AliHLTProcessor::DoEvent; + +private: + + /// Implements a ring buffer for old counter and time stamp values. + class AliRingBuffer : public TObject + { + public: + enum + { + /// The maximum number of time stamp entries held in the ring buffers for rate calculations. + /// The uncertainty in the rate should be ~ rate/sqrt(kTimeStampEntries) + kTimeStampEntries = 100 + }; + + /// Constructor initialises the buffer + AliRingBuffer(const char* counterName, Double_t startTime) : TObject(), fCounterName(counterName), fPos(0) + { + for (size_t i = 0; i < kTimeStampEntries; ++i) { + fCounterBuffer[i] = 0; fTimeBuffer[i] = startTime; + } + } + + /// Inherited form TObject. Returns the counter name this buffer is associated to. + virtual const char* GetName() const { return fCounterName.Data(); } + + /// Inherited from TObject. Returns a hash value calculated from the counter name. + virtual ULong_t Hash() const { return fCounterName.Hash(); } + + /// Returns the oldest counter value. + ULong64_t OldestCounter() const { return fCounterBuffer[fPos]; } + + /// Returns the oldest time value. + Double_t OldestTime() const { return fTimeBuffer[fPos]; } + + /** + * Increments the buffer. The new time and counter values are put into the + * current location to replace the existing values, then the current position + * is incremented (and wrapped around if necessary). + * \param newCounter The new counter value to put into the buffer. + * \param newTime The new time value to put into the buffer. + */ + void Increment(ULong64_t newCounter, Double_t newTime) + { + fCounterBuffer[fPos] = newCounter; + fTimeBuffer[fPos] = newTime; + fPos = (fPos+1) % kTimeStampEntries; + } + + private: + + TString fCounterName; // The name of the counter. + UInt_t fPos; // Current position in the buffers. + ULong64_t fCounterBuffer[kTimeStampEntries]; // The counter elements of the buffer. + Double_t fTimeBuffer[kTimeStampEntries]; // The time elements of the buffer. + }; + + // Do not allow copying of this class. + AliHLTTriggerCounterComponent(const AliHLTTriggerCounterComponent& obj); + AliHLTTriggerCounterComponent& operator = (const AliHLTTriggerCounterComponent& obj); + + /// Updates the counter rate value. + void UpdateCounterRate(AliHLTTriggerCounters::AliCounter* counter, AliRingBuffer* timeBuf, Double_t newTime); + + /// Loads the initial configuration of counters from the given CDB path. + int LoadConfigFromCDB(const char* cdbPath); + + /// Loads the initial configuration of counters from the given configuration file. + int LoadConfigFromFile(const char* configFile); + + /** + * Sets the initial counter values from a TMap object containing name description pairs. + * \param counters The list of counters to initialise. This TMap should contain TObjString + * pairs where the key is the name of the counter and the TMap value is the description. + * If the 14th bit is set in the key TObjString then the counter is considered an + * output counter and an input counter otherwise. + */ + void SetInitialCounters(const TMap* counters); + + double fOutputMultiplier; //! Multiplier value for the output size estimate. + AliHLTTriggerCounters fInputCounters; //! Input trigger counters. + AliHLTTriggerCounters fOutputCounters; //! Output trigger counters. + THashTable fInputTimes; //! Cyclic buffer storing the time stamps when the input counters were received. + THashTable fOutputTimes; //! Cyclic buffer storing the time stamps when the output counters were received. + Double_t fLastPublishTime; //! The last time the counters were pushed back to the output. + Double_t fPublishPeriod; //! The time between calls to push back the counters to output. + + static const char* fgkConfigCDBPath; //! CDB configuration path. + static TMap fgInitialCounterConfig; //! Initial configuration information for the counters. + + ClassDef(AliHLTTriggerCounterComponent, 0) // Component for counting HLT triggers. +}; + +#endif // ALIHLTTRIGGERCOUNTERCOMPONENT_H diff --git a/HLT/trigger/AliHLTTriggerLinkDef.h b/HLT/trigger/AliHLTTriggerLinkDef.h index c5465919f63..f90c99d8ac3 100644 --- a/HLT/trigger/AliHLTTriggerLinkDef.h +++ b/HLT/trigger/AliHLTTriggerLinkDef.h @@ -32,6 +32,7 @@ #pragma link C++ class AliHLTMuonSpectroScalars::AliScalar+; #pragma link C++ class AliHLTMuonSpectroTriggerComponent+; #pragma link C++ class AliHLTUpcTriggerComponent+; +#pragma link C++ class AliHLTTriggerCounterComponent+; #pragma link C++ class AliHLTTriggerCounters+; #pragma link C++ class AliHLTTriggerCounters::AliCounter+; diff --git a/HLT/trigger/test/InitialCounterConfig.C b/HLT/trigger/test/InitialCounterConfig.C new file mode 100644 index 00000000000..7c3e947479a --- /dev/null +++ b/HLT/trigger/test/InitialCounterConfig.C @@ -0,0 +1,33 @@ +// $Id: $ +/************************************************************************** + * This file is property of and copyright by the ALICE HLT Project * + * ALICE Experiment at CERN, All rights reserved. * + * * + * Primary Authors: Artur Szostak * + * 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 InitialCounterConfig.C +/// @author Artur Szostak +/// @date 12 Nov 2009 +/// @brief Implementation of initial counter configuration routine for testing. +/// +/// The InitialCounterConfig routine generates the initial counter configuration +/// to test the AliHLTTriggerCounterComponent class. + +void InitialCounterConfig() +{ + TMap& counters = AliHLTTriggerCounterComponent::InitialCounterConfig(); + counters.Add(new TObjString("CINTA"), new TObjString("Input interaction trigger")); + TObjString* name = new TObjString("TRIGGER-A"); + name->SetBit(1<<14); // mark as output trigger + counters.Add(name, new TObjString("Output trigger A")); +} diff --git a/HLT/trigger/test/Makefile.am b/HLT/trigger/test/Makefile.am index 1c7c1603b66..df28e00596a 100644 --- a/HLT/trigger/test/Makefile.am +++ b/HLT/trigger/test/Makefile.am @@ -8,7 +8,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/BASE \ EXTRA_DIST = -check_PROGRAMS = testTriggerDomain testGlobalTriggerComponent testMuonSpectroTrigger testAliHLTTriggerCounters +check_PROGRAMS = testTriggerDomain testGlobalTriggerComponent testMuonSpectroTrigger testAliHLTTriggerCounters testTriggerCounterComponent testTriggerDomain_SOURCES = testTriggerDomain.C @@ -18,6 +18,8 @@ testMuonSpectroTrigger_SOURCES = testMuonSpectroTrigger.C testAliHLTTriggerCounters_SOURCES = testAliHLTTriggerCounters.C +testTriggerCounterComponent_SOURCES = testTriggerCounterComponent.C + # linker flags LDADD_COMMON = $(top_builddir)/BASE/libHLTbase.la \ $(top_builddir)/MUON/libAliHLTMUON.la \ @@ -42,5 +44,8 @@ testMuonSpectroTrigger_LDFLAGS = $(LDFLAGS_COMMON) testAliHLTTriggerCounters_LDADD = $(LDADD_COMMON) testAliHLTTriggerCounters_LDFLAGS = $(LDFLAGS_COMMON) +testTriggerCounterComponent_LDADD = $(LDADD_COMMON) +testTriggerCounterComponent_LDFLAGS = $(LDFLAGS_COMMON) + TESTS = $(check_PROGRAMS) diff --git a/HLT/trigger/test/testTriggerCounterComponent.C b/HLT/trigger/test/testTriggerCounterComponent.C new file mode 100644 index 00000000000..051d2231493 --- /dev/null +++ b/HLT/trigger/test/testTriggerCounterComponent.C @@ -0,0 +1,408 @@ +/************************************************************************** + * This file is property of and copyright by the ALICE HLT Project * + * ALICE Experiment at CERN, All rights reserved. * + * * + * Primary Authors: Artur Szostak * + * 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 testTriggerCounterComponent.C + * @author Artur Szostak + * @date 5 Nov 2010 + * + * This macro is used to test the AliHLTTriggerCounterComponent class. + * Tests are run with component within the AliHLTSystem framework to check that + * the trigger counters are generated correctly by the component. + */ + +#if !defined(__CINT__) || defined(__MAKECINT__) +#include "TSystem.h" +#include "TFile.h" +#include "AliLog.h" +#include "AliHLTTriggerCounters.h" +#include "AliHLTTriggerDecision.h" +#include "AliHLTGlobalTriggerDecision.h" +#include "AliHLTSystem.h" +#include "AliHLTConfiguration.h" +#include "AliHLTCTPData.h" +#include "Riostream.h" +#endif + +/** + * Generates some sample input data and writes it into 9 files named + * testInputFileTriggerCounter1.root ... testInputFileTriggerCounter9.root + */ +void GenerateInputData() +{ + AliHLTTriggerDecision td1(true, "TRIGGER-A", AliHLTTriggerDomain("TRACKS:TPC")); + AliHLTTriggerDecision td1f(false, "TRIGGER-A", AliHLTTriggerDomain()); + AliHLTTriggerDecision td2(true, "TRIGGER-B", AliHLTTriggerDomain("CLUSTERS:TPC")); + AliHLTTriggerDecision td2f(false, "TRIGGER-B", AliHLTTriggerDomain()); + AliHLTTriggerDecision td3(true, "TRIGGER-C", AliHLTTriggerDomain("*******:***")); + AliHLTTriggerDecision td3f(false, "TRIGGER-C", AliHLTTriggerDomain()); + AliHLTGlobalTriggerDecision gd1(true, AliHLTTriggerDomain("TRACKS:TPC"), "TRIGGER-A"); + AliHLTGlobalTriggerDecision gd2(true, AliHLTTriggerDomain("CLUSTERS:TPC"), "TRIGGER-B"); + AliHLTGlobalTriggerDecision gd3(true, AliHLTTriggerDomain("*******:***"), "TRIGGER-B,TRIGGER-C"); + + AliHLTCTPData ctp("CTP_TRIGGER_CLASS=00:CINTA:17,01:CINTB:00-01-02-03-04-05-06-07-08-09-10-11-12-13-14-15-16-17,02:CMUB:00-10-11-17"); + gd1.AddInputObjectRef(&ctp); + gd2.AddInputObjectRef(&ctp); + gd3.AddInputObjectRef(&ctp); + + TFile* file = new TFile("testInputFileTriggerCounter1.root", "RECREATE"); + ctp.Increment(int(0)); + gd1.Write("HLTGlobalTrigger"); + td1.Write("Trigger"); + delete file; + + file = new TFile("testInputFileTriggerCounter2.root", "RECREATE"); + ctp.Increment(int(1)); + gd2.Write("HLTGlobalTrigger"); + td1f.Write("Trigger"); + td2.Write("Trigger"); + td3f.Write("Trigger"); + delete file; + + file = new TFile("testInputFileTriggerCounter3.root", "RECREATE"); + ctp.Increment(int(2)); + gd3.Write("HLTGlobalTrigger"); + td1f.Write("Trigger"); + td2.Write("Trigger"); + td3.Write("Trigger"); + delete file; + + gd1.AddTriggerInput(td1); + gd2.AddTriggerInput(td1f); + gd2.AddTriggerInput(td2); + gd2.AddTriggerInput(td3f); + gd3.AddTriggerInput(td1f); + gd3.AddTriggerInput(td2); + gd3.AddTriggerInput(td3); + + file = new TFile("testInputFileTriggerCounter4.root", "RECREATE"); + ctp.Increment(int(0)); + gd1.Write("HLTGlobalTrigger"); + td1.Write("Trigger"); + delete file; + + file = new TFile("testInputFileTriggerCounter5.root", "RECREATE"); + ctp.Increment(int(1)); + gd2.Write("HLTGlobalTrigger"); + td1f.Write("Trigger"); + td2.Write("Trigger"); + delete file; + + file = new TFile("testInputFileTriggerCounter6.root", "RECREATE"); + ctp.Increment(int(2)); + gd3.Write("HLTGlobalTrigger"); + td1f.Write("Trigger"); + td2.Write("Trigger"); + td3.Write("Trigger"); + delete file; + + file = new TFile("testInputFileTriggerCounter7.root", "RECREATE"); + ctp.Increment(int(0)); + gd1.Write("HLTGlobalTrigger"); + delete file; + + file = new TFile("testInputFileTriggerCounter8.root", "RECREATE"); + ctp.Increment(int(1)); + gd2.Write("HLTGlobalTrigger"); + delete file; + + file = new TFile("testInputFileTriggerCounter9.root", "RECREATE"); + ctp.Increment(int(2)); + gd3.Write("HLTGlobalTrigger"); + delete file; +} + +/** + * Runs a small chain with the HLTTriggerCounter component to generate output that + * can be checked. + * \param debug If true then full debug logging is enabled. + * \param numOfEvents The number of events to run the chain for. + */ +void RunTriggerCounter(bool debug = false, int numOfEvents = 9) +{ + AliHLTSystem sys; + sys.LoadComponentLibraries("libAliHLTUtil.so"); + sys.LoadComponentLibraries("libAliHLTTRD.so"); + sys.LoadComponentLibraries("libAliHLTMUON.so"); + sys.LoadComponentLibraries("libAliHLTTrigger.so"); + if (debug) + { + AliLog::SetGlobalLogLevel(AliLog::kMaxType); + sys.SetGlobalLoggingLevel(kHLTLogAll); + } + + TString cmdline = "-datatype GLOBTRIG 'HLT ' -objectname HLTGlobalTrigger "; + for (int i = 1; i <= 9; i++) + { + if (i > 1) cmdline += " -nextevent"; + cmdline += Form(" -datafile testInputFileTriggerCounter%d.root", i); + } + AliHLTConfiguration pub1("pub1", "ROOTFilePublisher", NULL, cmdline.Data()); + cmdline = "-datatype TRIG_DEC 'HLT ' -objectname Trigger "; + for (int i = 1; i <= 9; i++) + { + if (i > 1) cmdline += " -nextevent"; + cmdline += Form(" -datafile testInputFileTriggerCounter%d.root", i); + } + AliHLTConfiguration pub2("pub2", "ROOTFilePublisher", NULL, cmdline.Data()); + AliHLTConfiguration proc("proc", "HLTTriggerCounter", "pub1 pub2", "-skipcdb -config InitialCounterConfig.C"); + AliHLTConfiguration sink("sink", "ROOTFileWriter", "proc", "-datafile testOutputFileTriggerCounter.root -concatenate-events"); + sys.BuildTaskList("sink"); + sys.Run(numOfEvents); +} + +/** + * Checks that the input and output counters have the expected values or not. + * If they do not an appropriate error message is printed. + * \param eventNum The number of the event being checked. + * \param inputCounters The input counters to check. + * \param outputCounters The output counters to check. + * \param expectedInputCounters The expected input counter values to check against. + * \param expectedOutputCounters The expected output counter values to check against. + * \param expectedDescription The expected resulting trigger description. + * \returns true if the counters are correct and false otherwise. + */ +bool CheckCounters( + int eventNum, + AliHLTTriggerCounters* inputCounters, + AliHLTTriggerCounters* outputCounters, + AliHLTTriggerCounters& expectedInputCounters, + AliHLTTriggerCounters& expectedOutputCounters + ) +{ + if (inputCounters == NULL) + { + cerr << "ERROR: No trigger input counters were found for event " + << eventNum << "." << endl; + return false; + } + if (outputCounters == NULL) + { + cerr << "ERROR: No trigger output counters were found for event " + << eventNum << "." << endl; + return false; + } + // Copy over the Rates because these might not be identical since they are a + // run time parameter. The counter value and name must be identical however. + for (UInt_t i = 0; i < inputCounters->NumberOfCounters() && i < expectedInputCounters.NumberOfCounters(); ++i) + { + expectedInputCounters.GetCounterN(i).Rate( inputCounters->GetCounterN(i).Rate() ); + } + for (UInt_t i = 0; i < outputCounters->NumberOfCounters() && i < expectedOutputCounters.NumberOfCounters(); ++i) + { + expectedOutputCounters.GetCounterN(i).Rate( outputCounters->GetCounterN(i).Rate() ); + } + bool inputCountersAsExpected = (inputCounters->NumberOfCounters() == expectedInputCounters.NumberOfCounters()); + bool outputCountersAsExpected = (outputCounters->NumberOfCounters() == expectedOutputCounters.NumberOfCounters()); + for (UInt_t i = 0; i < inputCounters->NumberOfCounters() && i < expectedInputCounters.NumberOfCounters(); ++i) + { + if (strcmp(expectedInputCounters.GetCounterN(i).Name(), inputCounters->GetCounterN(i).Name()) != 0) + { + inputCountersAsExpected = false; + break; + } + if (expectedInputCounters.GetCounterN(i).Counter() != inputCounters->GetCounterN(i).Counter()) + { + inputCountersAsExpected = false; + break; + } + } + for (UInt_t i = 0; i < outputCounters->NumberOfCounters() && i < expectedOutputCounters.NumberOfCounters(); ++i) + { + if (strcmp(expectedOutputCounters.GetCounterN(i).Name(), outputCounters->GetCounterN(i).Name()) != 0) + { + outputCountersAsExpected = false; + break; + } + if (expectedOutputCounters.GetCounterN(i).Counter() != outputCounters->GetCounterN(i).Counter()) + { + outputCountersAsExpected = false; + break; + } + } + if (! inputCountersAsExpected) + { + cerr << "ERROR: The trigger input counters do not match the expected set of counters for event " + << eventNum << "." << endl; + cout << "Found the following input counters: " << endl; // using cout since Print() goes there. + inputCounters->Print(); + cout << "But expected the following input counters: " << endl; + expectedInputCounters.Print(); + return false; + } + if (! outputCountersAsExpected) + { + cerr << "ERROR: The trigger output counters do not match the expected set of counters for event " + << eventNum << "." << endl; + cout << "Found the following output counters: " << endl; // using cout since Print() goes there. + outputCounters->Print(); + cout << "But expected the following output counters: " << endl; + expectedOutputCounters.Print(); + return false; + } + return true; +} + + +/// Routine for checking the results file generated by the RunTriggerCounter routine. +bool CheckTriggerCounterOutput() +{ + AliHLTTriggerCounters expectedInputCounters[11]; + AliHLTTriggerCounters expectedOutputCounters[11]; + + // Start-of-run event (should contain no values) + expectedInputCounters[0].Add("CINTA", "", 0, 0); + expectedOutputCounters[0].Add("TRIGGER-A", "", 0, 0); + + // Data events + expectedInputCounters[1].Add("CINTA", "", 0, 1); + expectedInputCounters[1].Add("CINTB", "", 0, 0); + expectedInputCounters[1].Add("CMUB", "", 0, 0); + expectedInputCounters[1].Add("TRIGGER-A", "", 0, 1); + expectedOutputCounters[1].Add("TRIGGER-A", "", 0, 1); + + expectedInputCounters[2].Add("CINTA", "", 0, 1); + expectedInputCounters[2].Add("CINTB", "", 0, 1); + expectedInputCounters[2].Add("CMUB", "", 0, 0); + expectedInputCounters[2].Add("TRIGGER-A", "", 0, 1); + expectedInputCounters[2].Add("TRIGGER-B", "", 0, 1); + expectedOutputCounters[2].Add("TRIGGER-A", "", 0, 1); + expectedOutputCounters[2].Add("TRIGGER-B", "", 0, 1); + + expectedInputCounters[3].Add("CINTA", "", 0, 1); + expectedInputCounters[3].Add("CINTB", "", 0, 1); + expectedInputCounters[3].Add("CMUB", "", 0, 1); + expectedInputCounters[3].Add("TRIGGER-A", "", 0, 1); + expectedInputCounters[3].Add("TRIGGER-B", "", 0, 2); + expectedInputCounters[3].Add("TRIGGER-C", "", 0, 1); + expectedOutputCounters[3].Add("TRIGGER-A", "", 0, 1); + expectedOutputCounters[3].Add("TRIGGER-B", "", 0, 2); + expectedOutputCounters[3].Add("TRIGGER-C", "", 0, 1); + + expectedInputCounters[4].Add("CINTA", "", 0, 2); + expectedInputCounters[4].Add("CINTB", "", 0, 1); + expectedInputCounters[4].Add("CMUB", "", 0, 1); + expectedInputCounters[4].Add("TRIGGER-A", "", 0, 2); + expectedInputCounters[4].Add("TRIGGER-B", "", 0, 2); + expectedInputCounters[4].Add("TRIGGER-C", "", 0, 1); + expectedOutputCounters[4].Add("TRIGGER-A", "", 0, 2); + expectedOutputCounters[4].Add("TRIGGER-B", "", 0, 2); + expectedOutputCounters[4].Add("TRIGGER-C", "", 0, 1); + + expectedInputCounters[5].Add("CINTA", "", 0, 2); + expectedInputCounters[5].Add("CINTB", "", 0, 2); + expectedInputCounters[5].Add("CMUB", "", 0, 1); + expectedInputCounters[5].Add("TRIGGER-A", "", 0, 2); + expectedInputCounters[5].Add("TRIGGER-B", "", 0, 3); + expectedInputCounters[5].Add("TRIGGER-C", "", 0, 1); + expectedOutputCounters[5].Add("TRIGGER-A", "", 0, 2); + expectedOutputCounters[5].Add("TRIGGER-B", "", 0, 3); + expectedOutputCounters[5].Add("TRIGGER-C", "", 0, 1); + + expectedInputCounters[6].Add("CINTA", "", 0, 2); + expectedInputCounters[6].Add("CINTB", "", 0, 2); + expectedInputCounters[6].Add("CMUB", "", 0, 2); + expectedInputCounters[6].Add("TRIGGER-A", "", 0, 2); + expectedInputCounters[6].Add("TRIGGER-B", "", 0, 4); + expectedInputCounters[6].Add("TRIGGER-C", "", 0, 2); + expectedOutputCounters[6].Add("TRIGGER-A", "", 0, 2); + expectedOutputCounters[6].Add("TRIGGER-B", "", 0, 4); + expectedOutputCounters[6].Add("TRIGGER-C", "", 0, 2); + + expectedInputCounters[7].Add("CINTA", "", 0, 3); + expectedInputCounters[7].Add("CINTB", "", 0, 2); + expectedInputCounters[7].Add("CMUB", "", 0, 2); + expectedInputCounters[7].Add("TRIGGER-A", "", 0, 3); + expectedInputCounters[7].Add("TRIGGER-B", "", 0, 4); + expectedInputCounters[7].Add("TRIGGER-C", "", 0, 2); + expectedOutputCounters[7].Add("TRIGGER-A", "", 0, 3); + expectedOutputCounters[7].Add("TRIGGER-B", "", 0, 4); + expectedOutputCounters[7].Add("TRIGGER-C", "", 0, 2); + + expectedInputCounters[8].Add("CINTA", "", 0, 3); + expectedInputCounters[8].Add("CINTB", "", 0, 3); + expectedInputCounters[8].Add("CMUB", "", 0, 2); + expectedInputCounters[8].Add("TRIGGER-A", "", 0, 3); + expectedInputCounters[8].Add("TRIGGER-B", "", 0, 5); + expectedInputCounters[8].Add("TRIGGER-C", "", 0, 2); + expectedOutputCounters[8].Add("TRIGGER-A", "", 0, 3); + expectedOutputCounters[8].Add("TRIGGER-B", "", 0, 5); + expectedOutputCounters[8].Add("TRIGGER-C", "", 0, 2); + + expectedInputCounters[9].Add("CINTA", "", 0, 3); + expectedInputCounters[9].Add("CINTB", "", 0, 3); + expectedInputCounters[9].Add("CMUB", "", 0, 3); + expectedInputCounters[9].Add("TRIGGER-A", "", 0, 3); + expectedInputCounters[9].Add("TRIGGER-B", "", 0, 6); + expectedInputCounters[9].Add("TRIGGER-C", "", 0, 3); + expectedOutputCounters[9].Add("TRIGGER-A", "", 0, 3); + expectedOutputCounters[9].Add("TRIGGER-B", "", 0, 6); + expectedOutputCounters[9].Add("TRIGGER-C", "", 0, 3); + + // End-of-run event + expectedInputCounters[10].Add("CINTA", "", 0, 3); + expectedInputCounters[10].Add("CINTB", "", 0, 3); + expectedInputCounters[10].Add("CMUB", "", 0, 3); + expectedInputCounters[10].Add("TRIGGER-A", "", 0, 3); + expectedInputCounters[10].Add("TRIGGER-B", "", 0, 6); + expectedInputCounters[10].Add("TRIGGER-C", "", 0, 3); + expectedOutputCounters[10].Add("TRIGGER-A", "", 0, 3); + expectedOutputCounters[10].Add("TRIGGER-B", "", 0, 6); + expectedOutputCounters[10].Add("TRIGGER-C", "", 0, 3); + + TFile* file = new TFile("testOutputFileTriggerCounter.root", "READ"); + for (int i = 0; i < 11; ++i) + { + AliHLTTriggerCounters* inputCounters = dynamic_cast( file->Get(Form("AliHLTTriggerCounters;%d", i*2+1)) ); + AliHLTTriggerCounters* outputCounters = dynamic_cast( file->Get(Form("AliHLTTriggerCounters;%d", i*2+2)) ); + if (! CheckCounters(i-1, inputCounters, outputCounters, expectedInputCounters[i], expectedOutputCounters[i])) + { + delete file; + return false; + } + } + delete file; + return true; +} + +/** + * Runs several tests for the AliHLTTriggerCounterComponent class. + * We specifically test if the generated counters are correctly generated. + * \param debug If true then full debug logging is enabled. + * \param numOfEvents The number of events to run the chain over. + * \returns true if all the tests succeeded and false otherwise. + */ +bool testTriggerCounterComponent(bool debug = false, int numOfEvents = 9) +{ + GenerateInputData(); + RunTriggerCounter(debug, numOfEvents); + if (! CheckTriggerCounterOutput()) return false; + // Cleanup all temporary files generated. + gSystem->Exec("rm -f testOutputFileTriggerCounter.root testInputFileTriggerCounter*.root"); + return true; +} + + +#ifndef __MAKECINT__ + +int main(int /*argc*/, const char** /*argv*/) +{ + bool resultOk = testTriggerCounterComponent(); + if (not resultOk) return 1; + return 0; +} + +#endif // __MAKECINT__ -- 2.39.3