From 2320590d8cb51d24501eaaa45fb1911d899a8024 Mon Sep 17 00:00:00 2001 From: Ben Blamey Date: Thu, 18 Jul 2024 23:15:34 +0200 Subject: [PATCH] added warning to c++ solvers when variables are specified for non-variable solvers. fixes StochSS/GillesPy2#955. --- gillespy2/solvers/cpp/ode_c_solver.py | 3 ++ gillespy2/solvers/cpp/ssa_c_solver.py | 2 + gillespy2/solvers/cpp/tau_hybrid_c_solver.py | 3 ++ gillespy2/solvers/cpp/tau_leaping_c_solver.py | 5 ++- test/test_variable_solvers.py | 44 +++++++++++++++++++ 5 files changed, 56 insertions(+), 1 deletion(-) diff --git a/gillespy2/solvers/cpp/ode_c_solver.py b/gillespy2/solvers/cpp/ode_c_solver.py index 7278a0fe..9478f718 100644 --- a/gillespy2/solvers/cpp/ode_c_solver.py +++ b/gillespy2/solvers/cpp/ode_c_solver.py @@ -151,6 +151,9 @@ def run(self=None, model: Model = None, t: int = None, number_of_trajectories: i "init_pop": populations, "parameters": parameter_values }) + elif variables: + log.warning("'variables' argument ignored, because solver has variable=False.") + if integrator_options is not None: integrator_options = ODECSolver.validate_integrator_options(integrator_options) args.update(integrator_options) diff --git a/gillespy2/solvers/cpp/ssa_c_solver.py b/gillespy2/solvers/cpp/ssa_c_solver.py index 52253d60..a4f8ee2a 100644 --- a/gillespy2/solvers/cpp/ssa_c_solver.py +++ b/gillespy2/solvers/cpp/ssa_c_solver.py @@ -143,6 +143,8 @@ def run(self=None, model: Model = None, t: int = None, number_of_trajectories: i "init_pop": populations, "parameters": parameter_values }) + elif variables: + log.warning("'variables' argument ignored, because solver has variable=False.") seed = self._validate_seed(seed) if seed is not None: diff --git a/gillespy2/solvers/cpp/tau_hybrid_c_solver.py b/gillespy2/solvers/cpp/tau_hybrid_c_solver.py index 75847c46..8d4befbe 100644 --- a/gillespy2/solvers/cpp/tau_hybrid_c_solver.py +++ b/gillespy2/solvers/cpp/tau_hybrid_c_solver.py @@ -325,6 +325,9 @@ def run(self=None, model: Model = None, t: int = None, number_of_trajectories: i "init_pop": populations, "parameters": parameter_values }) + elif variables: + log.warning("'variables' argument ignored, because solver has variable=False.") + if integrator_options is not None: integrator_options = TauHybridCSolver.validate_integrator_options(integrator_options) args.update(integrator_options) diff --git a/gillespy2/solvers/cpp/tau_leaping_c_solver.py b/gillespy2/solvers/cpp/tau_leaping_c_solver.py index c52042d3..7b6148fd 100644 --- a/gillespy2/solvers/cpp/tau_leaping_c_solver.py +++ b/gillespy2/solvers/cpp/tau_leaping_c_solver.py @@ -19,7 +19,7 @@ from gillespy2.solvers.utilities import solverutils as cutils from gillespy2.core import GillesPySolver, Model from gillespy2.core.gillespyError import * -from gillespy2.core import Results +from gillespy2.core import Results, log from .c_solver import CSolver, SimulationReturnCode @@ -68,6 +68,7 @@ def run(self=None, model: Model = None, t: int = None, number_of_trajectories: i increment: int = None, seed: int = None, debug: bool = False, profile: bool = False, variables={}, resume=None, live_output: str = None, live_output_options: dict = {}, tau_tol=0.03, constant_tau_stepsize=None, **kwargs): + """ :param model: The model on which the solver will operate. (Deprecated) :type model: gillespy2.Model @@ -172,6 +173,8 @@ def run(self=None, model: Model = None, t: int = None, number_of_trajectories: i "init_pop": populations, "parameters": parameter_values }) + elif variables: + log.warning("'variables' argument ignored, because solver has variable=False.") seed = self._validate_seed(seed) if seed is not None: diff --git a/test/test_variable_solvers.py b/test/test_variable_solvers.py index 78d08ad9..097f4956 100644 --- a/test/test_variable_solvers.py +++ b/test/test_variable_solvers.py @@ -14,6 +14,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +import logging import unittest import tempfile from gillespy2.core.gillespyError import DirectoryError, SimulationError @@ -73,6 +74,49 @@ def test_invalid_variable(self): for solver in self.solverlist: results = self.model.run(solver=solver, variables={'foobar':0}) + def test_non_variable_solver_ignored_variables_warnings(self): + """ + Ensure that non-variable solvers emit warnings for ignored variables. + """ + nonVarSolverList = [SSACSolver(self.model, variable=False), + ODECSolver(self.model, variable=False), + TauLeapingCSolver(self.model, variable=False), + TauHybridCSolver(self.model, variable=False)] + for nonVarSolver in nonVarSolverList: + with self.subTest(msg=f"for non-variable {nonVarSolver.__class__.__name__}"): + with self.subTest(msg="when variables is specified"): + self.model.run(solver=nonVarSolver, variables={'k1':1}) + self.assertLogs(level=logging.WARN) + with self.subTest(msg="when variables is not specified"): + self.model.run(solver=nonVarSolver) + if hasattr(self, 'assertNoLogs'): # Python >= 3.10 only + self.assertNoLogs(level=logging.WARN) + with self.subTest(msg="when variables is {}"): + self.model.run(solver=nonVarSolver, variables={}) + if hasattr(self, 'assertNoLogs'): # Python >= 3.10 only + self.assertNoLogs(level=logging.WARN) + + def test_variable_solver_ignored_variables_warnings(self): + """ + Ensure that variable solvers do not emit warnings related to non-variable + solver variable ignoring. + """ + for varSolver in self.solverlist: + with self.subTest(msg=f"for variable {varSolver}"): + with self.subTest(msg="when variables is specified"): + self.model.run(solver=varSolver, variables={'k1':1}) + if hasattr(self, 'assertNoLogs'): # Python >= 3.10 only + self.assertNoLogs(level=logging.WARN) + with self.subTest(msg="when variables is not specified"): + self.model.run(solver=varSolver) + if hasattr(self, 'assertNoLogs'): # Python >= 3.10 only + self.assertNoLogs(level=logging.WARN) + with self.subTest(msg="when variables is {}"): + self.model.run(solver=varSolver, variables={}) + if hasattr(self, 'assertNoLogs'): # Python >= 3.10 only + self.assertNoLogs(level=logging.WARN) + + if __name__ == '__main__': unittest.main()