From a87fdf30e9fa9656b8225b753240abe8ac76b721 Mon Sep 17 00:00:00 2001 From: Charles Burton <burton@utexas.edu> Date: Wed, 3 Jul 2019 09:33:19 +0000 Subject: [PATCH] Offline Naming Convention --- .../AthenaMonitoring/GenericMonitoringTool.h | 1 + .../AthenaMonitoring/HistogramDef.h | 2 + .../python/AthMonitorCfgHelper.py | 3 +- .../python/GenericMonitoringTool.py | 7 +- Control/AthenaMonitoring/share/GenericMon.txt | 10 +-- .../src/ExampleMonitorAlgorithm.cxx | 2 +- .../src/GenericMonitoringTool.cxx | 4 ++ Control/AthenaMonitoring/src/HistogramDef.cxx | 1 + .../src/HistogramFiller/HistogramFactory.cxx | 24 ++++--- .../src/HistogramFiller/HistogramFactory.h | 3 +- .../HistogramFillerFactory.cxx | 5 +- .../OfflineHistogramProvider.h | 72 +++++++++++++++++++ .../test/GenericMonParsing_test.cxx | 14 ++-- .../test/HistogramFactoryTestSuite.cxx | 10 +++ .../LumiblockHistogramProviderTestSuite.cxx | 31 ++++++++ .../test/mocks/MockGenericMonitoringTool.h | 5 ++ .../test/test_defineHistogram.py | 22 +++--- 17 files changed, 180 insertions(+), 36 deletions(-) create mode 100644 Control/AthenaMonitoring/src/HistogramFiller/OfflineHistogramProvider.h diff --git a/Control/AthenaMonitoring/AthenaMonitoring/GenericMonitoringTool.h b/Control/AthenaMonitoring/AthenaMonitoring/GenericMonitoringTool.h index d16bcaf6562..004977975d6 100644 --- a/Control/AthenaMonitoring/AthenaMonitoring/GenericMonitoringTool.h +++ b/Control/AthenaMonitoring/AthenaMonitoring/GenericMonitoringTool.h @@ -91,6 +91,7 @@ public: void setPath( const std::string& newPath ) { m_histoPath = newPath; } virtual const ServiceHandle<ITHistSvc>& histogramService() { return m_histSvc; } + virtual uint32_t runNumber(); virtual uint32_t lumiBlock(); private: /// THistSvc (do NOT fix the service type (only the name) to allow for a different implementation online diff --git a/Control/AthenaMonitoring/AthenaMonitoring/HistogramDef.h b/Control/AthenaMonitoring/AthenaMonitoring/HistogramDef.h index 901749673ff..a2cc2afa22c 100644 --- a/Control/AthenaMonitoring/AthenaMonitoring/HistogramDef.h +++ b/Control/AthenaMonitoring/AthenaMonitoring/HistogramDef.h @@ -25,6 +25,8 @@ namespace Monitored { std::string path; //!< booking path std::string title; //!< title of the histogram std::string opt; //!< options + std::string tld{""}; //!< top level directory (below THistSvc stream) + std::string convention; //!< path naming convention (e.g. OFFLINE) std::string weight; //!< names of weights int xbins{0}; //!< number of bins in X diff --git a/Control/AthenaMonitoring/python/AthMonitorCfgHelper.py b/Control/AthenaMonitoring/python/AthMonitorCfgHelper.py index 4f34c6c1589..3a61fa213b8 100644 --- a/Control/AthenaMonitoring/python/AthMonitorCfgHelper.py +++ b/Control/AthenaMonitoring/python/AthMonitorCfgHelper.py @@ -76,7 +76,7 @@ class AthMonitorCfgHelper(object): self.monSeq += algObj return algObj - def addGroup(self, alg, name, topPath=''): + def addGroup(self, alg, name, topPath='', duration='run'): ''' Add a "group" (technically, a GenericMonitoringTool instance) to an algorithm. The name given here can be used to retrieve the group from within the algorithm when calling the fill() @@ -101,6 +101,7 @@ class AthMonitorCfgHelper(object): self.resobj.merge(acc) tool.HistPath = self.inputFlags.DQ.FileKey + ('/%s' % topPath if topPath else '') + tool.convention = 'OFFLINE:'+duration alg.GMTools += [tool] return tool diff --git a/Control/AthenaMonitoring/python/GenericMonitoringTool.py b/Control/AthenaMonitoring/python/GenericMonitoringTool.py index f4cc01cf95d..4a591018ae1 100644 --- a/Control/AthenaMonitoring/python/GenericMonitoringTool.py +++ b/Control/AthenaMonitoring/python/GenericMonitoringTool.py @@ -15,6 +15,8 @@ class GenericMonitoringTool(_GenericMonitoringTool): super(GenericMonitoringTool, self).__init__(name, **kwargs) def defineHistogram(self, *args, **kwargs): + if 'convention' not in kwargs and hasattr(self,'convention'): + kwargs['convention'] = self.convention self.Histograms.append(defineHistogram(*args, **kwargs)) ## Generate histogram definition string for the `GenericMonitoringTool.Histograms` property @@ -32,7 +34,8 @@ def defineHistogram(varname, type='TH1F', path=None, title=None,weight='', xbins=100, xmin=0, xmax=1, ybins=None, ymin=None, ymax=None, - zmin=None, zmax=None, opt='', labels=None): + zmin=None, zmax=None, + opt='', labels=None, convention=''): # Assert argument types assert path is not None, "path is required" @@ -47,7 +50,7 @@ def defineHistogram(varname, type='TH1F', path=None, log.warning('Histogram %s of type %s is not supported for online running and will not be added', varname, type) return "" - coded = "%s, %s, %s, %s, %s, " % (path, type, weight, varname, title) + coded = "%s, %s, %s, %s, %s, %s, " % (path, type, weight, convention, varname, title) if not isinstance(xbins,list): coded += '%d, %f, %f' % (xbins, xmin, xmax) diff --git a/Control/AthenaMonitoring/share/GenericMon.txt b/Control/AthenaMonitoring/share/GenericMon.txt index 7678aed82c6..2cf20a93de6 100644 --- a/Control/AthenaMonitoring/share/GenericMon.txt +++ b/Control/AthenaMonitoring/share/GenericMon.txt @@ -16,10 +16,10 @@ THistSvc.OutputLevel = 0; THistSvc.Output= {"EXPERT DATAFILE='expert-monitoring.root' OPT='RECREATE'" }; ToolSvc.MonTool.OutputLevel =0; ToolSvc.MonTool.HistPath="TestGroup"; -ToolSvc.MonTool.Histograms = { "EXPERT, TH1F, , Eta, #eta of Clusters; #eta; number of RoIs, 2, -2.500000, 2.500000" }; -ToolSvc.MonTool.Histograms += { "EXPERT, TH1F, , Phi, #phi of Clusters; #phi; number of RoIs, 2, -3.15, 3.15" }; -ToolSvc.MonTool.Histograms += { "EXPERT, TH2F, , Eta,Phi, #eta vs #phi of Clusters; #eta; #phi; number of RoIs, 2, -2.500000, 2.500000, 2, -3.15, 3.15" }; -ToolSvc.MonTool.Histograms += { "EXPERT, TH1F, , TIME_t1, Timing of tool 1, 100, 0., 1000." }; -ToolSvc.MonTool.Histograms += { "EXPERT, TH1F, , TIME_t2, Timing of tool 2, 100, 0., 1000." }; +ToolSvc.MonTool.Histograms = { "EXPERT, TH1F, , , Eta, #eta of Clusters; #eta; number of RoIs, 2, -2.500000, 2.500000" }; +ToolSvc.MonTool.Histograms += { "EXPERT, TH1F, , , Phi, #phi of Clusters; #phi; number of RoIs, 2, -3.15, 3.15" }; +ToolSvc.MonTool.Histograms += { "EXPERT, TH2F, , , Eta,Phi, #eta vs #phi of Clusters; #eta; #phi; number of RoIs, 2, -2.500000, 2.500000, 2, -3.15, 3.15" }; +ToolSvc.MonTool.Histograms += { "EXPERT, TH1F, , , TIME_t1, Timing of tool 1, 100, 0., 1000." }; +ToolSvc.MonTool.Histograms += { "EXPERT, TH1F, , , TIME_t2, Timing of tool 2, 100, 0., 1000." }; diff --git a/Control/AthenaMonitoring/src/ExampleMonitorAlgorithm.cxx b/Control/AthenaMonitoring/src/ExampleMonitorAlgorithm.cxx index ed38e8189b2..6fd4bcab827 100644 --- a/Control/AthenaMonitoring/src/ExampleMonitorAlgorithm.cxx +++ b/Control/AthenaMonitoring/src/ExampleMonitorAlgorithm.cxx @@ -30,7 +30,7 @@ StatusCode ExampleMonitorAlgorithm::fillHistograms( const EventContext& ctx ) co // Two variables (value and passed) needed for TEfficiency auto pT = Monitored::Scalar<float>("pT",0.0); - auto pT_passed = Monitored::Scalar<float>("pT_passed",false); + auto pT_passed = Monitored::Scalar<bool>("pT_passed",false); // Set the values of the monitored variables for the event lumiPerBCID = lbAverageInteractionsPerCrossing (ctx); diff --git a/Control/AthenaMonitoring/src/GenericMonitoringTool.cxx b/Control/AthenaMonitoring/src/GenericMonitoringTool.cxx index 14da4a06204..b30d31ed209 100644 --- a/Control/AthenaMonitoring/src/GenericMonitoringTool.cxx +++ b/Control/AthenaMonitoring/src/GenericMonitoringTool.cxx @@ -133,6 +133,10 @@ std::vector<std::shared_ptr<HistogramFiller>> GenericMonitoringTool::getHistogra return result; } +uint32_t GenericMonitoringTool::runNumber() { + return Gaudi::Hive::currentContext().eventID().run_number(); +} + uint32_t GenericMonitoringTool::lumiBlock() { return Gaudi::Hive::currentContext().eventID().lumi_block(); } diff --git a/Control/AthenaMonitoring/src/HistogramDef.cxx b/Control/AthenaMonitoring/src/HistogramDef.cxx index b12dae054a0..9d7c9234f53 100644 --- a/Control/AthenaMonitoring/src/HistogramDef.cxx +++ b/Control/AthenaMonitoring/src/HistogramDef.cxx @@ -25,6 +25,7 @@ const HistogramDef HistogramDef::parse(const std::string &histogramDefinition) { result.path = nextProperty(propertiesIterator); result.type = nextProperty(propertiesIterator); result.weight = nextProperty(propertiesIterator); + result.convention = nextProperty(propertiesIterator); result.name.push_back(nextProperty(propertiesIterator)); if (result.type.compare(0, 3, "TH2") == 0 || result.type == "TProfile" || result.type == "TEfficiency") { diff --git a/Control/AthenaMonitoring/src/HistogramFiller/HistogramFactory.cxx b/Control/AthenaMonitoring/src/HistogramFiller/HistogramFactory.cxx index cf7c92f78e5..57f7f8c76c7 100644 --- a/Control/AthenaMonitoring/src/HistogramFiller/HistogramFactory.cxx +++ b/Control/AthenaMonitoring/src/HistogramFiller/HistogramFactory.cxx @@ -14,8 +14,14 @@ using namespace Monitored; HistogramFactory::HistogramFactory(const ServiceHandle<ITHistSvc>& histSvc, - std::string groupName) - : m_histSvc(histSvc), m_groupName(std::move(groupName)) {} + std::string histoPath) +: m_histSvc(histSvc) +{ + size_t split = histoPath.find('/'); + m_streamName = histoPath.substr(0,split); + m_groupName = split!=std::string::npos ? histoPath.substr(split) : ""; +} + TNamed* HistogramFactory::create(const HistogramDef& def) { TNamed* rootObj(0); @@ -191,15 +197,15 @@ std::string HistogramFactory::getFullName(const HistogramDef& def) { const static std::set<std::string> online( { "EXPERT", "SHIFT", "DEBUG", "RUNSTAT", "EXPRES" } ); std::string path; - if( online.count( def.path) != 0 ) { - path = "/" + def.path + "/" + m_groupName; - } else if ( def.path == "DEFAULT" ) { - path = "/" + m_groupName; + if ( online.count( def.path)!=0 ) { + path = "/" + def.path + "/" + m_streamName + "/" + m_groupName; + } else if ( def.path=="DEFAULT" ) { + path = "/" + m_streamName + "/" + m_groupName; } else { - path = "/" + m_groupName + "/"+def.path; + path = "/" + m_streamName + "/" + def.tld + "/" + m_groupName + "/" + def.path; } - - // remove duplicate + + // remove duplicate slashes std::string fullName = path + "/" + def.alias; fullName.erase( std::unique( fullName.begin(), fullName.end(), [](const char a, const char b) { diff --git a/Control/AthenaMonitoring/src/HistogramFiller/HistogramFactory.h b/Control/AthenaMonitoring/src/HistogramFiller/HistogramFactory.h index 3f7a2fdea64..2b730f4ef1f 100644 --- a/Control/AthenaMonitoring/src/HistogramFiller/HistogramFactory.h +++ b/Control/AthenaMonitoring/src/HistogramFiller/HistogramFactory.h @@ -136,7 +136,8 @@ namespace Monitored { std::string getFullName(const HistogramDef& def); ServiceHandle<ITHistSvc> m_histSvc; - std::string m_groupName; //!< defines location of histograms + std::string m_streamName; //!< defines the stream for THistSvc + std::string m_groupName; //!< defines location of group of histograms }; } diff --git a/Control/AthenaMonitoring/src/HistogramFiller/HistogramFillerFactory.cxx b/Control/AthenaMonitoring/src/HistogramFiller/HistogramFillerFactory.cxx index 8a45168d7b2..ef8fb73bcba 100644 --- a/Control/AthenaMonitoring/src/HistogramFiller/HistogramFillerFactory.cxx +++ b/Control/AthenaMonitoring/src/HistogramFiller/HistogramFillerFactory.cxx @@ -6,6 +6,7 @@ #include "StaticHistogramProvider.h" #include "LumiblockHistogramProvider.h" +#include "OfflineHistogramProvider.h" #include "HistogramFiller1D.h" #include "HistogramFillerEfficiency.h" @@ -52,7 +53,9 @@ HistogramFiller* HistogramFillerFactory::create(const HistogramDef& def) { std::shared_ptr<IHistogramProvider> HistogramFillerFactory::createHistogramProvider(const HistogramDef& def) { std::shared_ptr<IHistogramProvider> result; - if (def.opt.find("kLBNHistoryDepth") != std::string::npos) { + if ( def.convention.find("OFFLINE") != std::string::npos ) { + result.reset(new OfflineHistogramProvider(m_gmTool, m_factory, def)); + } else if (def.opt.find("kLBNHistoryDepth") != std::string::npos) { result.reset(new LumiblockHistogramProvider(m_gmTool, m_factory, def)); } else { result.reset(new StaticHistogramProvider(m_factory, def)); diff --git a/Control/AthenaMonitoring/src/HistogramFiller/OfflineHistogramProvider.h b/Control/AthenaMonitoring/src/HistogramFiller/OfflineHistogramProvider.h new file mode 100644 index 00000000000..eac044669a3 --- /dev/null +++ b/Control/AthenaMonitoring/src/HistogramFiller/OfflineHistogramProvider.h @@ -0,0 +1,72 @@ +/* + Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef AthenaMonitoring_HistogramFiller_OfflineHistogramProvider_h +#define AthenaMonitoring_HistogramFiller_OfflineHistogramProvider_h + +#include <memory> + +#include "AthenaMonitoring/GenericMonitoringTool.h" +#include "AthenaMonitoring/HistogramDef.h" +#include "AthenaMonitoring/IHistogramProvider.h" + +#include "HistogramFactory.h" + +namespace Monitored { + /** + * @brief Implementation of IHistogramProvider for offline histograms + */ + class OfflineHistogramProvider : public IHistogramProvider { + public: + /** + * @brief Constructor + * + * @param gmTool Source of the lumi block info + * @param factory ROOT object factory + * @param def General definition of a histogram + */ + OfflineHistogramProvider(GenericMonitoringTool* const gmTool, + std::shared_ptr<HistogramFactory> factory, + const HistogramDef& histDef) + : IHistogramProvider() + , m_gmTool(gmTool) + , m_factory(factory) + , m_histDef(new HistogramDef(histDef)) + {} + + /** + * @brief Getter of ROOT object + * + * Each time the method is called, factory produces ROOT object based on the current + * lumi block. Note: ROOT objects are cached at the factory. Nevertheless, it is + * recommended to call this method as rarely as possible. + * + * @return ROOT object + */ + TNamed* histogram() override { + const unsigned runNumber = m_gmTool->runNumber(); + const unsigned lumiBlock = m_gmTool->lumiBlock(); + + std::string conv = m_histDef->convention; + std::string lbString; + if ( conv.find("run")!=std::string::npos ) { + lbString = "/run"; + } else if ( conv.find("lowStat")!=std::string::npos ) { + const unsigned lbBase = lumiBlock-(lumiBlock%20); + lbString = "/lowStat"+std::to_string(lbBase)+"-"+std::to_string(lbBase+20); + } else { + lbString = "/lb_"+std::to_string(lumiBlock); + } + m_histDef->tld = "/run_"+std::to_string(runNumber)+lbString+"/"; + + return m_factory->create(*m_histDef); + } + + GenericMonitoringTool* const m_gmTool; + std::shared_ptr<HistogramFactory> m_factory; + std::shared_ptr<HistogramDef> m_histDef; + }; +} + +#endif /* AthenaMonitoring_HistogramFiller_OfflineHistogramProvider_h */ \ No newline at end of file diff --git a/Control/AthenaMonitoring/test/GenericMonParsing_test.cxx b/Control/AthenaMonitoring/test/GenericMonParsing_test.cxx index c7e2429f104..7c766a4f7fd 100644 --- a/Control/AthenaMonitoring/test/GenericMonParsing_test.cxx +++ b/Control/AthenaMonitoring/test/GenericMonParsing_test.cxx @@ -16,7 +16,7 @@ using namespace Monitored; bool parsing1DWorks() { - auto def = HistogramDef::parse("EXPERT, TH1F, , Eta, #eta of Clusters; #eta; number of RoIs, 50, -2.500000, 2.500000"); + auto def = HistogramDef::parse("EXPERT, TH1F, , , Eta, #eta of Clusters; #eta; number of RoIs, 50, -2.500000, 2.500000"); VALUE ( def.ok ) EXPECTED ( true ); VALUE ( def.path ) EXPECTED ( "EXPERT" ); VALUE ( def.type ) EXPECTED ( "TH1F" ); @@ -30,7 +30,7 @@ bool parsing1DWorks() { } bool parsing2DWorks() { - auto def = HistogramDef::parse("SHIFT, TH2F, , Eta,Phi, #eta vs #phi of Clusters; #eta; #phi, 50, -2.500000, 2.500000, 64, -3.200000, 3.200000"); + auto def = HistogramDef::parse("SHIFT, TH2F, , , Eta,Phi, #eta vs #phi of Clusters; #eta; #phi, 50, -2.500000, 2.500000, 64, -3.200000, 3.200000"); VALUE ( def.ok ) EXPECTED ( true ) ; VALUE ( def.path ) EXPECTED ( "SHIFT" ); VALUE ( def.type ) EXPECTED ( "TH2F" ); @@ -50,7 +50,7 @@ bool parsing2DWorks() { } bool parsing3DWorks() { - auto def = HistogramDef::parse("SHIFT, TProfile2D, , Eta,Phi,pt, title, 50, -2.500000, 2.500000, 64, -3.200000, 3.200000, -1.000000, 1.000000"); + auto def = HistogramDef::parse("SHIFT, TProfile2D, , , Eta,Phi,pt, title, 50, -2.500000, 2.500000, 64, -3.200000, 3.200000, -1.000000, 1.000000"); VALUE ( def.ok ) EXPECTED ( true ) ; VALUE ( def.path ) EXPECTED ( "SHIFT" ); VALUE ( def.type ) EXPECTED ( "TProfile2D" ); @@ -72,7 +72,7 @@ bool parsing3DWorks() { } bool parsingLabeledWorks() { - auto def = HistogramDef::parse("SHIFT, TH1D, , Cut, Cut counter, 5, 0, 5, Cut1:Cut2:Eta:Pt:R"); + auto def = HistogramDef::parse("SHIFT, TH1D, , , Cut, Cut counter, 5, 0, 5, Cut1:Cut2:Eta:Pt:R"); VALUE ( def.ok ) EXPECTED ( true ) ; VALUE ( def.path ) EXPECTED ( "SHIFT" ); VALUE ( def.type ) EXPECTED ( "TH1D" ); @@ -89,7 +89,7 @@ bool parsingLabeledWorks() { } bool parsingWeightedWorks() { - auto def = HistogramDef::parse("EXPERT, TH1F, Weight, var, title, 5, 0, 5"); + auto def = HistogramDef::parse("EXPERT, TH1F, Weight, , var, title, 5, 0, 5"); VALUE ( def.ok ) EXPECTED ( true ); VALUE ( def.path ) EXPECTED ( "EXPERT" ); VALUE ( def.type ) EXPECTED ( "TH1F" ); @@ -101,7 +101,7 @@ bool parsingWeightedWorks() { } bool parsing1DArrayWorks() { - auto def = HistogramDef::parse("EXPERT, TH1F, , var, title, 0:1:2:4:8"); + auto def = HistogramDef::parse("EXPERT, TH1F, , , var, title, 0:1:2:4:8"); VALUE ( def.ok ) EXPECTED ( true ); VALUE ( def.xbins ) EXPECTED ( 4 ); VALUE ( std::equal(def.xArray.begin(),def.xArray.end(),std::vector<double>({0,1,2,4,8}).begin()) ) EXPECTED ( true ); @@ -109,7 +109,7 @@ bool parsing1DArrayWorks() { } bool parsing2DArrayWorks() { - auto def = HistogramDef::parse("EXPERT, TH2F, , var1,var2, title, 0:1:2:4:8, 0:4:6:7"); + auto def = HistogramDef::parse("EXPERT, TH2F, , , var1,var2, title, 0:1:2:4:8, 0:4:6:7"); VALUE ( def.ok ) EXPECTED ( true ); VALUE ( def.xbins ) EXPECTED ( 4 ); VALUE ( std::equal(def.xArray.begin(),def.xArray.end(),std::vector<double>({0,1,2,4,8}).begin()) ) EXPECTED ( true ); diff --git a/Control/AthenaMonitoring/test/HistogramFactoryTestSuite.cxx b/Control/AthenaMonitoring/test/HistogramFactoryTestSuite.cxx index f6608da9bb1..750dd99f1f5 100644 --- a/Control/AthenaMonitoring/test/HistogramFactoryTestSuite.cxx +++ b/Control/AthenaMonitoring/test/HistogramFactoryTestSuite.cxx @@ -47,6 +47,7 @@ class HistogramFactoryTestSuite { REGISTER_TEST_CASE(test_shouldProperlyFormatPathForOnlineHistograms), REGISTER_TEST_CASE(test_shouldProperlyFormatPathForDefaultHistograms), REGISTER_TEST_CASE(test_shouldProperlyFormatPathForCustomHistograms), + REGISTER_TEST_CASE(test_shouldProperlyFormatPathForOfflineHistograms), REGISTER_TEST_CASE(test_shouldSetXAxisLabelsFor1DHistogram), REGISTER_TEST_CASE(test_shouldSetXAndYAxisLabelsFor2DHistogram), REGISTER_TEST_CASE(test_shouldSetExtendAxesWhenkCanRebinIsSet), @@ -168,6 +169,15 @@ class HistogramFactoryTestSuite { VALUE(m_histSvc->exists("/HistogramFactoryTestSuite/custom/path/for/histogram/customAlias")) EXPECTED(true); } + void test_shouldProperlyFormatPathForOfflineHistograms() { + HistogramDef histogramDef = defaultHistogramDef("TH1F"); + histogramDef.path = "/custom/path/for/histogram"; + histogramDef.alias = "offlineAlias"; + histogramDef.tld = "/run_XXXXXX/lbYYY/"; + m_testObj->create(histogramDef); + VALUE(m_histSvc->exists("/HistogramFactoryTestSuite/run_XXXXXX/lbYYY/custom/path/for/histogram/offlineAlias")) EXPECTED(true); + } + void test_shouldSetXAxisLabelsFor1DHistogram() { HistogramDef histogramDef = defaultHistogramDef("TH1F"); histogramDef.alias = "labels1DTestAlias"; diff --git a/Control/AthenaMonitoring/test/LumiblockHistogramProviderTestSuite.cxx b/Control/AthenaMonitoring/test/LumiblockHistogramProviderTestSuite.cxx index e1b47506e0a..a67b7df3c1e 100644 --- a/Control/AthenaMonitoring/test/LumiblockHistogramProviderTestSuite.cxx +++ b/Control/AthenaMonitoring/test/LumiblockHistogramProviderTestSuite.cxx @@ -26,6 +26,7 @@ #include "mocks/MockHistogramFactory.h" #include "../src/HistogramFiller/LumiblockHistogramProvider.h" +#include "../src/HistogramFiller/OfflineHistogramProvider.h" using namespace std; using namespace Monitored; @@ -41,6 +42,7 @@ class LumiblockHistogramProviderTestSuite { REGISTER_TEST_CASE(test_shouldThrowExceptionWhen_kLBNHistoryDepth_isDefinedAs_NaN), REGISTER_TEST_CASE(test_shouldNotThrowExceptionWhen_kLBNHistoryDepth_isDefinedAsNumber), REGISTER_TEST_CASE(test_shouldCreateNewHistogramWithUpdatedAlias), + REGISTER_TEST_CASE(test_shouldCreateNewHistogramWithUpdatedLumiBlock), }; } @@ -117,6 +119,35 @@ class LumiblockHistogramProviderTestSuite { } } + void test_shouldCreateNewHistogramWithUpdatedLumiBlock() { + auto expectedFlow = { + make_tuple(100, 100000, "/run_100000/lowStat100-120/"), + make_tuple(125, 200000, "/run_200000/lowStat120-140/"), + }; + + TNamed histogram; + HistogramDef histogramDef; + histogramDef.convention = "OFFLINE:lowStat"; + + OfflineHistogramProvider testObj(m_gmTool.get(), m_histogramFactory, histogramDef); + + for (auto input : expectedFlow) { + const unsigned lumiBlock = get<0>(input); + const unsigned runNumber = get<1>(input); + const string expectedTld = get<2>(input); + + m_gmTool->mock_lumiBlock = [lumiBlock]() { return lumiBlock; }; + m_gmTool->mock_runNumber = [runNumber]() { return runNumber; }; + m_histogramFactory->mock_create = [&histogram, expectedTld](const HistogramDef& def) mutable { + VALUE(def.tld) EXPECTED(expectedTld); + return &histogram; + }; + + TNamed* const result = testObj.histogram(); + VALUE(result) EXPECTED(&histogram); + } + } + // ==================== Helper methods ==================== private: diff --git a/Control/AthenaMonitoring/test/mocks/MockGenericMonitoringTool.h b/Control/AthenaMonitoring/test/mocks/MockGenericMonitoringTool.h index a4a751e8d56..3ee54722ff8 100644 --- a/Control/AthenaMonitoring/test/mocks/MockGenericMonitoringTool.h +++ b/Control/AthenaMonitoring/test/mocks/MockGenericMonitoringTool.h @@ -18,6 +18,11 @@ class MockGenericMonitoringTool : public GenericMonitoringTool { return mock_lumiBlock ? mock_lumiBlock() : 0; } + std::function<uint32_t()> mock_runNumber; + uint32_t runNumber() override { + return mock_runNumber ? mock_runNumber() : 0; + } + const ServiceHandle<ITHistSvc>& histogramService() override { m_serviceHandle.retrieve(); diff --git a/Control/AthenaMonitoring/test/test_defineHistogram.py b/Control/AthenaMonitoring/test/test_defineHistogram.py index 21b794f1729..94e16522c62 100644 --- a/Control/AthenaMonitoring/test/test_defineHistogram.py +++ b/Control/AthenaMonitoring/test/test_defineHistogram.py @@ -9,27 +9,27 @@ from AthenaMonitoring.GenericMonitoringTool import defineHistogram class Test( unittest.TestCase ): def test_1D( self ): s = defineHistogram('var', 'TH1F', 'EXPERT', 'title', '', 10, 0.0, 10.0) - self.assertEqual(s, 'EXPERT, TH1F, , var, title, 10, 0.000000, 10.000000') + self.assertEqual(s, 'EXPERT, TH1F, , , var, title, 10, 0.000000, 10.000000') def test_1D_label( self ): s = defineHistogram('var', 'TH1F', 'EXPERT', 'title', '', 10, 0.0, 10.0, labels=['a','b']) - self.assertEqual(s, 'EXPERT, TH1F, , var, title, 10, 0.000000, 10.000000, a:b:') + self.assertEqual(s, 'EXPERT, TH1F, , , var, title, 10, 0.000000, 10.000000, a:b:') def test_1D_opt( self ): s = defineHistogram('var', 'TH1F', 'EXPERT', 'title', '', 10, 0.0, 10.0, opt='myopt') - self.assertEqual(s, 'EXPERT, TH1F, , var, title, 10, 0.000000, 10.000000, myopt') + self.assertEqual(s, 'EXPERT, TH1F, , , var, title, 10, 0.000000, 10.000000, myopt') def test_1D_weight( self ): s = defineHistogram('var', 'TH1F', 'EXPERT', 'title', 'weight', 10, 0.0, 10.0) - self.assertEqual(s, 'EXPERT, TH1F, weight, var, title, 10, 0.000000, 10.000000') + self.assertEqual(s, 'EXPERT, TH1F, weight, , var, title, 10, 0.000000, 10.000000') def test_2D( self ): s = defineHistogram('var1,var2', 'TH2F', 'EXPERT', 'title', '', 10, 0.0, 10.0, 20, 0.0, 20.0) - self.assertEqual(s, 'EXPERT, TH2F, , var1,var2, title, 10, 0.000000, 10.000000, 20, 0.000000, 20.000000') + self.assertEqual(s, 'EXPERT, TH2F, , , var1,var2, title, 10, 0.000000, 10.000000, 20, 0.000000, 20.000000') def test_3D( self ): s = defineHistogram('var1,var2,var3', 'TProfile2D', 'EXPERT', 'title', '', 10, 0.0, 10.0, 20, 0.0, 20.0, -1.0, 1.0) - self.assertEqual(s, 'EXPERT, TProfile2D, , var1,var2,var3, title, 10, 0.000000, 10.000000, 20, 0.000000, 20.000000, -1.000000, 1.000000') + self.assertEqual(s, 'EXPERT, TProfile2D, , , var1,var2,var3, title, 10, 0.000000, 10.000000, 20, 0.000000, 20.000000, -1.000000, 1.000000') def test_enforcePath( self ): with self.assertRaises(AssertionError): @@ -41,15 +41,19 @@ class Test( unittest.TestCase ): def test_efficiency( self ): s = defineHistogram('var', 'TEfficiency', 'EXPERT', 'title', '', 10, 0.0, 10.0) - self.assertEqual(s, 'EXPERT, TEfficiency, , var, title, 10, 0.000000, 10.000000') + self.assertEqual(s, 'EXPERT, TEfficiency, , , var, title, 10, 0.000000, 10.000000') def test_1D_array( self ): s = defineHistogram('var', 'TH1F', 'EXPERT', 'title', '', [0,1,2,4,8]) - self.assertEqual(s, 'EXPERT, TH1F, , var, title, 0:1:2:4:8') + self.assertEqual(s, 'EXPERT, TH1F, , , var, title, 0:1:2:4:8') def test_2D_array( self ): s = defineHistogram('var1,var2', 'TH2F', 'EXPERT', 'title', '', [0,1,2], ybins=[1,2,3,7]) - self.assertEqual(s, 'EXPERT, TH2F, , var1,var2, title, 0:1:2, 1:2:3:7') + self.assertEqual(s, 'EXPERT, TH2F, , , var1,var2, title, 0:1:2, 1:2:3:7') + + def test_nameConvention( self ): + s = defineHistogram('var', 'TH1F', 'path', 'title', '', 10, 0.0, 10.0, convention='OFFLINE:lowStat') + self.assertEqual(s, 'path, TH1F, , OFFLINE:lowStat, var, title, 10, 0.000000, 10.000000') if __name__ == '__main__': unittest.main() -- GitLab