diff --git a/bindings/pyroot/pythonizations/test/tf_pycallables.py b/bindings/pyroot/pythonizations/test/tf_pycallables.py index 2a7d6b7246238..1a5611aa859a5 100644 --- a/bindings/pyroot/pythonizations/test/tf_pycallables.py +++ b/bindings/pyroot/pythonizations/test/tf_pycallables.py @@ -5,8 +5,8 @@ Cppyy that creates a C++ wrapper to invoke the Python callable. """ -import unittest import math +import unittest import ROOT @@ -23,14 +23,17 @@ class pyf_tf1_callable: def __call__(self, x, p): return p[0] * x[0] + p[1] + def pyf_func(x, pars): return pars[0] * x[0] * x[2] + x[1] * pars[1] + def pyf_tf1_gauss(x, p): - return p[0] * 1.0 / math.sqrt(2.0 * math.pi * p[2]**2) * math.exp(-(x[0] - p[1])**2 / 2.0 / p[2]**2) + return p[0] * 1.0 / math.sqrt(2.0 * math.pi * p[2] ** 2) * math.exp(-((x[0] - p[1]) ** 2) / 2.0 / p[2] ** 2) + def pyf_tf1_coulomb(x, p): - return p[1] * x[0] * x[1] / (p[0]**2) * math.exp(-p[2] / p[0]) + return p[1] * x[0] * x[1] / (p[0] ** 2) * math.exp(-p[2] / p[0]) class TF1(unittest.TestCase): @@ -73,24 +76,23 @@ def test_callable(self): for x in [0.0, -1.0, 42.0]: self.assertEqual(f.Eval(x), pycallable([x], [par1, par2])) - def test_fitgauss(self): """ Test fitting a histogram to a Python function """ # Gaus function f = ROOT.TF1("tf1_fitgauss", pyf_tf1_gauss, -4, 4, 3) - f.SetParameter(0, 10.0) # scale - f.SetParameter(1, -1.0) # mean - f.SetParameter(2, 2.0) # standard deviation + f.SetParameter(0, 10.0) # scale + f.SetParameter(1, -1.0) # mean + f.SetParameter(2, 2.0) # standard deviation # Sample gauss in histogram h = ROOT.TH1F("h", "test", 100, -4, 4) h.FillRandom("gaus", 100000) - h.Scale(1.0 / 100000.0 * 100.0 / 8.0) # Normalize as density + h.Scale(1.0 / 100000.0 * 100.0 / 8.0) # Normalize as density # Fit to histogram and get parameters - h.Fit( f, "0Q" ) + h.Fit(f, "0Q") scale = f.GetParameter(0) mean = f.GetParameter(1) std = f.GetParameter(2) @@ -108,19 +110,15 @@ def test_evalpar(self): rtf1_coulomb = ROOT.TF1("my_func", pyf_tf1_coulomb, -10, 10) # x dataset: 5 pairs of particle charges - x = np.array([ - [1.0, 10, 2.0], - [1.5, 10, 2.5], - [2.0, 10, 3.0], - [2.5, 10, 3.5], - [3.0, 10, 4.0] - ]) - - params = np.array([ - [1.0], # Distance between charges r - [8.99e9], # Coulomb constant k (in N·m²/C²) - [0.1] # Additional factor for modulation - ]) + x = np.array([[1.0, 10, 2.0], [1.5, 10, 2.5], [2.0, 10, 3.0], [2.5, 10, 3.5], [3.0, 10, 4.0]]) + + params = np.array( + [ + 1.0, # Distance between charges r + 8.99e9, # Coulomb constant k (in N·m²/C²) + 0.1, # Additional factor for modulation + ] + ) # Slice to avoid the dummy column of 10's res = rtf1_coulomb.EvalPar(x[:, ::2], params) @@ -128,7 +126,7 @@ def test_evalpar(self): for i in range(len(x)): expected_value = pyf_tf1_coulomb(x[i, ::2], params) self.assertEqual(res[i], expected_value) - + def test_evalpar_dynamic(self): """ Test the 2D NumPy pythonizations with dynamic TF1 data dimensions @@ -139,12 +137,9 @@ def test_evalpar_dynamic(self): rtf1_func = ROOT.TF1("my_func", pyf_func, -10, 10) # x dataset with ndims 3 - x = np.array([[2., 2, 1], - [1., 2, 3], - [2., 2, 1], - [4., 3, 2]]) + x = np.array([[2.0, 2, 1], [1.0, 2, 3], [2.0, 2, 1], [4.0, 3, 2]]) - pars = np.array([2., 3.]) + pars = np.array([2.0, 3.0]) res = rtf1_func.EvalPar(x, pars) for i in range(len(x)): @@ -204,6 +199,5 @@ def test_params(self): self.assertEqual(f.Eval(*x), pyf_tf2_params(x, [par1, par2, par3, par4])) -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() - diff --git a/tutorials/CMakeLists.txt b/tutorials/CMakeLists.txt index 532c43d4b94a1..59ea6e78103be 100644 --- a/tutorials/CMakeLists.txt +++ b/tutorials/CMakeLists.txt @@ -349,9 +349,9 @@ else() # Keras tutorials. This mirrors the logic in tmva/sofie/test/CMakeLists.txt. # TODO: make sure we also support the newest Keras set(unsupported_keras_version "3.5.0") - if (NOT DEFINED ROOT_KERAS_VERSION) + if (ROOT_KERAS_FOUND AND NOT DEFINED ROOT_KERAS_VERSION) message(WARNING "Keras found, but version unknown — cannot verify compatibility.") - elseif (NOT ROOT_KERAS_VERSION VERSION_LESS ${unsupported_keras_version}) + elseif (ROOT_KERAS_FOUND AND NOT ROOT_KERAS_VERSION VERSION_LESS ${unsupported_keras_version}) message(WARNING "Keras version ${ROOT_KERAS_VERSION} is too new for the SOFIE Keras parser (only supports < ${unsupported_keras_version}). Corresponding tutorials will not be tested.") set(keras_unsupported TRUE) endif()