From c12179bd4867768d0d7adb19ba85e1659623dfda Mon Sep 17 00:00:00 2001 From: Bertrand Bellenot Date: Mon, 6 Jul 2026 13:04:26 +0200 Subject: [PATCH 1/2] [win] Fix testRooFitHS3 linker error on Windows Fix the following linker error on Windows: testRooFitHS3.obj : error LNK2001: unresolved external symbol "public: static bool RooJSONFactoryWSTool::importNoDomainParametersAsRooConstVars" (?importNoDomainParametersAsRooConstVars@RooJSONFactoryWSTool@@2_NA) --- .../hs3/inc/RooFitHS3/RooJSONFactoryWSTool.h | 9 ++++++ roofit/hs3/src/RooJSONFactoryWSTool.cxx | 31 +++++++++++++++++++ roofit/hs3/test/testRooFitHS3.cxx | 6 ++-- 3 files changed, 43 insertions(+), 3 deletions(-) diff --git a/roofit/hs3/inc/RooFitHS3/RooJSONFactoryWSTool.h b/roofit/hs3/inc/RooFitHS3/RooJSONFactoryWSTool.h index 4f13181d1d250..75d71f5009703 100644 --- a/roofit/hs3/inc/RooFitHS3/RooJSONFactoryWSTool.h +++ b/roofit/hs3/inc/RooFitHS3/RooJSONFactoryWSTool.h @@ -54,6 +54,15 @@ class RooJSONFactoryWSTool { ~RooJSONFactoryWSTool(); + static bool getAllowExportInvalidNames(); + static void setAllowExportInvalidNames(bool allow); + + static bool getAllowSanitizeNames(); + static void setAllowSanitizeNames(bool allow); + + static bool getImportNoDomainParametersAsRooConstVars(); + static void setImportNoDomainParametersAsRooConstVars(bool val); + static std::string name(const RooFit::Detail::JSONNode &n); static bool isValidName(const std::string &str); static bool testValidName(const std::string &str, bool forcError); diff --git a/roofit/hs3/src/RooJSONFactoryWSTool.cxx b/roofit/hs3/src/RooJSONFactoryWSTool.cxx index 0d93c738aae54..910c701a2e1f0 100644 --- a/roofit/hs3/src/RooJSONFactoryWSTool.cxx +++ b/roofit/hs3/src/RooJSONFactoryWSTool.cxx @@ -984,6 +984,37 @@ bool RooJSONFactoryWSTool::isValidName(const std::string &str) bool RooJSONFactoryWSTool::allowExportInvalidNames(true); bool RooJSONFactoryWSTool::allowSanitizeNames(true); bool RooJSONFactoryWSTool::importNoDomainParametersAsRooConstVars(true); + +bool RooJSONFactoryWSTool::getAllowExportInvalidNames() +{ + return allowExportInvalidNames; +} + +void RooJSONFactoryWSTool::setAllowExportInvalidNames(bool allow) +{ + allowExportInvalidNames = allow; +} + +bool RooJSONFactoryWSTool::getAllowSanitizeNames() +{ + return allowSanitizeNames; +} + +void RooJSONFactoryWSTool::setAllowSanitizeNames(bool allow) +{ + allowSanitizeNames = allow; +} + +bool RooJSONFactoryWSTool::getImportNoDomainParametersAsRooConstVars() +{ + return importNoDomainParametersAsRooConstVars; +} + +void RooJSONFactoryWSTool::setImportNoDomainParametersAsRooConstVars(bool val) +{ + importNoDomainParametersAsRooConstVars = val; +} + bool RooJSONFactoryWSTool::testValidName(const std::string &name, bool forceError) { if (!RooJSONFactoryWSTool::isValidName(name)) { diff --git a/roofit/hs3/test/testRooFitHS3.cxx b/roofit/hs3/test/testRooFitHS3.cxx index 3fcf10dc044de..747942729ee68 100644 --- a/roofit/hs3/test/testRooFitHS3.cxx +++ b/roofit/hs3/test/testRooFitHS3.cxx @@ -169,12 +169,12 @@ std::string defaultDomainAxesNode(std::string const &json) class ScopedNoDomainConstVarImportFlag { public: explicit ScopedNoDomainConstVarImportFlag(bool value) - : _oldValue{RooJSONFactoryWSTool::importNoDomainParametersAsRooConstVars} + : _oldValue{RooJSONFactoryWSTool::getImportNoDomainParametersAsRooConstVars()} { - RooJSONFactoryWSTool::importNoDomainParametersAsRooConstVars = value; + RooJSONFactoryWSTool::setImportNoDomainParametersAsRooConstVars(value); } - ~ScopedNoDomainConstVarImportFlag() { RooJSONFactoryWSTool::importNoDomainParametersAsRooConstVars = _oldValue; } + ~ScopedNoDomainConstVarImportFlag() { RooJSONFactoryWSTool::setImportNoDomainParametersAsRooConstVars(_oldValue); } private: bool _oldValue; From 3240fd8e8fdf9422e82d67a54568fd97bde453ae Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Tue, 7 Jul 2026 08:20:29 +0200 Subject: [PATCH 2/2] [RF][HS3] Use single static config function for RooJSONFactoryWSTool This avoids bolerplate code with getters and setters for each static configuration variable. --- .../hs3/inc/RooFitHS3/RooJSONFactoryWSTool.h | 21 ++++---- roofit/hs3/src/RooJSONFactoryWSTool.cxx | 48 ++++--------------- roofit/hs3/test/testRooFitHS3.cxx | 9 ++-- 3 files changed, 25 insertions(+), 53 deletions(-) diff --git a/roofit/hs3/inc/RooFitHS3/RooJSONFactoryWSTool.h b/roofit/hs3/inc/RooFitHS3/RooJSONFactoryWSTool.h index 75d71f5009703..cad0f33f70c8b 100644 --- a/roofit/hs3/inc/RooFitHS3/RooJSONFactoryWSTool.h +++ b/roofit/hs3/inc/RooFitHS3/RooJSONFactoryWSTool.h @@ -39,9 +39,15 @@ class ModelConfig; class RooJSONFactoryWSTool { public: static constexpr bool useListsInsteadOfDicts = true; - static bool allowExportInvalidNames; - static bool allowSanitizeNames; - static bool importNoDomainParametersAsRooConstVars; + + struct Config { + bool allowExportInvalidNames = true; + bool allowSanitizeNames = true; + bool importNoDomainParametersAsRooConstVars = true; + }; + + static Config &config(); + static RooWorkspace sanitizeWS(const RooWorkspace &ws); static RooWorkspace cleanWS(const RooWorkspace &ws, bool onlyModelConfig = false); @@ -54,15 +60,6 @@ class RooJSONFactoryWSTool { ~RooJSONFactoryWSTool(); - static bool getAllowExportInvalidNames(); - static void setAllowExportInvalidNames(bool allow); - - static bool getAllowSanitizeNames(); - static void setAllowSanitizeNames(bool allow); - - static bool getImportNoDomainParametersAsRooConstVars(); - static void setImportNoDomainParametersAsRooConstVars(bool val); - static std::string name(const RooFit::Detail::JSONNode &n); static bool isValidName(const std::string &str); static bool testValidName(const std::string &str, bool forcError); diff --git a/roofit/hs3/src/RooJSONFactoryWSTool.cxx b/roofit/hs3/src/RooJSONFactoryWSTool.cxx index 910c701a2e1f0..da9a51d2a1a4a 100644 --- a/roofit/hs3/src/RooJSONFactoryWSTool.cxx +++ b/roofit/hs3/src/RooJSONFactoryWSTool.cxx @@ -981,47 +981,13 @@ bool RooJSONFactoryWSTool::isValidName(const std::string &str) return true; } -bool RooJSONFactoryWSTool::allowExportInvalidNames(true); -bool RooJSONFactoryWSTool::allowSanitizeNames(true); -bool RooJSONFactoryWSTool::importNoDomainParametersAsRooConstVars(true); - -bool RooJSONFactoryWSTool::getAllowExportInvalidNames() -{ - return allowExportInvalidNames; -} - -void RooJSONFactoryWSTool::setAllowExportInvalidNames(bool allow) -{ - allowExportInvalidNames = allow; -} - -bool RooJSONFactoryWSTool::getAllowSanitizeNames() -{ - return allowSanitizeNames; -} - -void RooJSONFactoryWSTool::setAllowSanitizeNames(bool allow) -{ - allowSanitizeNames = allow; -} - -bool RooJSONFactoryWSTool::getImportNoDomainParametersAsRooConstVars() -{ - return importNoDomainParametersAsRooConstVars; -} - -void RooJSONFactoryWSTool::setImportNoDomainParametersAsRooConstVars(bool val) -{ - importNoDomainParametersAsRooConstVars = val; -} - bool RooJSONFactoryWSTool::testValidName(const std::string &name, bool forceError) { if (!RooJSONFactoryWSTool::isValidName(name)) { std::stringstream ss; ss << "RooJSONFactoryWSTool() name '" << name << "' is not valid!" << std::endl - << "Sanitize names by setting RooJSONFactoryWSTool::allowSanitizeNames = True." << std::endl; - if (RooJSONFactoryWSTool::allowExportInvalidNames && !forceError) { + << "Sanitize names by setting RooJSONFactoryWSTool::config().allowSanitizeNames = true." << std::endl; + if (RooJSONFactoryWSTool::config().allowExportInvalidNames && !forceError) { RooJSONFactoryWSTool::warning(ss.str()); return false; } else { @@ -1832,7 +1798,7 @@ void RooJSONFactoryWSTool::importVariable(const JSONNode &p) oocoutE(nullptr, InputArguments) << ss.str() << std::endl; return; } - if (importNoDomainParametersAsRooConstVars && !_domains->hasVariable(name.c_str())) { + if (config().importNoDomainParametersAsRooConstVars && !_domains->hasVariable(name.c_str())) { if (!p.has_child("value")) { RooJSONFactoryWSTool::error("cannot instantiate RooConstVar '" + name + "' without \"value\"!"); } @@ -2549,7 +2515,7 @@ void RooJSONFactoryWSTool::error(const char *s) std::string RooJSONFactoryWSTool::sanitizeName(const std::string str) { std::string result; - if (RooJSONFactoryWSTool::allowSanitizeNames) { + if (RooJSONFactoryWSTool::config().allowSanitizeNames) { for (char c : str) { switch (c) { case '[': @@ -2622,6 +2588,12 @@ RooWorkspace RooJSONFactoryWSTool::cleanWS(const RooWorkspace &ws, bool onlyMode return tmpWS; } +RooJSONFactoryWSTool::Config &RooJSONFactoryWSTool::config() +{ + static Config conf; + return conf; +} + // Sanitize all names in the workspace to be HS3 compliant RooWorkspace RooJSONFactoryWSTool::sanitizeWS(const RooWorkspace &ws) { diff --git a/roofit/hs3/test/testRooFitHS3.cxx b/roofit/hs3/test/testRooFitHS3.cxx index 747942729ee68..5026e0699e9c0 100644 --- a/roofit/hs3/test/testRooFitHS3.cxx +++ b/roofit/hs3/test/testRooFitHS3.cxx @@ -169,12 +169,15 @@ std::string defaultDomainAxesNode(std::string const &json) class ScopedNoDomainConstVarImportFlag { public: explicit ScopedNoDomainConstVarImportFlag(bool value) - : _oldValue{RooJSONFactoryWSTool::getImportNoDomainParametersAsRooConstVars()} + : _oldValue{RooJSONFactoryWSTool::config().importNoDomainParametersAsRooConstVars} { - RooJSONFactoryWSTool::setImportNoDomainParametersAsRooConstVars(value); + RooJSONFactoryWSTool::config().importNoDomainParametersAsRooConstVars = value; } - ~ScopedNoDomainConstVarImportFlag() { RooJSONFactoryWSTool::setImportNoDomainParametersAsRooConstVars(_oldValue); } + ~ScopedNoDomainConstVarImportFlag() + { + RooJSONFactoryWSTool::config().importNoDomainParametersAsRooConstVars = _oldValue; + } private: bool _oldValue;