diff --git a/.github/workflows/copyright-test.yml b/.github/workflows/copyright-test.yml index 48a494d5..4f0c498f 100644 --- a/.github/workflows/copyright-test.yml +++ b/.github/workflows/copyright-test.yml @@ -17,10 +17,10 @@ jobs: steps: - uses: actions/checkout@v1 - - name: Set up Python 3.8 + - name: Set up Python 3.13 uses: actions/setup-python@v1 with: - python-version: 3.8 + python-version: 3.13 architecture: x64 - name: install chi diff --git a/.github/workflows/coverage-test.yml b/.github/workflows/coverage-test.yml index 77b3852c..39a38f47 100644 --- a/.github/workflows/coverage-test.yml +++ b/.github/workflows/coverage-test.yml @@ -17,12 +17,12 @@ jobs: steps: - uses: actions/checkout@v1 - - name: set up Python 3.8 + - name: set up Python 3.13 uses: actions/setup-python@v1 with: - python-version: 3.8 + python-version: 3.13 architecture: x64 - + - name: install sundials run: | sudo apt-get update diff --git a/.github/workflows/docs-test.yml b/.github/workflows/docs-test.yml index 8b6a84ec..e2b9662b 100644 --- a/.github/workflows/docs-test.yml +++ b/.github/workflows/docs-test.yml @@ -17,10 +17,10 @@ jobs: steps: - uses: actions/checkout@v1 - - name: Set up Python 3.8 + - name: Set up Python 3.13 uses: actions/setup-python@v1 with: - python-version: 3.8 + python-version: 3.13 architecture: x64 - name: install sundials (ubuntu) diff --git a/.github/workflows/style-test.yml b/.github/workflows/style-test.yml index f31de65c..a8c6a4c7 100644 --- a/.github/workflows/style-test.yml +++ b/.github/workflows/style-test.yml @@ -17,10 +17,10 @@ jobs: steps: - uses: actions/checkout@v1 - - name: Set up Python 3.8 + - name: Set up Python 3.13 uses: actions/setup-python@v1 with: - python-version: 3.8 + python-version: 3.13 architecture: x64 - name: install chi diff --git a/.github/workflows/unit-test-os-versions.yml b/.github/workflows/unit-test-os-versions.yml index 83a9be94..11c87482 100644 --- a/.github/workflows/unit-test-os-versions.yml +++ b/.github/workflows/unit-test-os-versions.yml @@ -17,12 +17,12 @@ jobs: os: [ubuntu-latest, windows-latest, macos-latest] steps: - - uses: actions/checkout@v1 + - uses: actions/checkout@v4 - - name: Set up Python 3.11 + - name: Set up Python 3.13 uses: actions/setup-python@v5 with: - python-version: 3.11 + python-version: 3.13 - name: install sundials (ubuntu) if: ${{ matrix.os == 'ubuntu-latest' }} diff --git a/.github/workflows/unit-test-python-versions.yml b/.github/workflows/unit-test-python-versions.yml index 177386b2..03eec323 100644 --- a/.github/workflows/unit-test-python-versions.yml +++ b/.github/workflows/unit-test-python-versions.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ['3.9', '3.10', '3.11'] + python-version: ['3.11', '3.12', '3.13'] steps: - uses: actions/checkout@v1 diff --git a/LICENSE.md b/LICENSE.md index 650d1356..32914e2a 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ BSD 3-Clause License -Copyright (c) 2024, David Augustin +Copyright (c) 2025, David Augustin All rights reserved. Redistribution and use in source and binary forms, with or without diff --git a/chi/_log_pdfs.py b/chi/_log_pdfs.py index c47cd8f5..daf848b0 100644 --- a/chi/_log_pdfs.py +++ b/chi/_log_pdfs.py @@ -818,7 +818,7 @@ def __call__(self, parameters): 'An error occured while solving the mechanistic model: \n' + str(e) + '.\n A score of -infinity is returned.', RuntimeWarning) - return -np.infty + return -np.inf # Remember only error parameters parameters = parameters[self._n_mechanistic_params:] @@ -993,7 +993,7 @@ def evaluateS1(self, parameters): + str(e) + '.\n A score of -infinity is returned.', RuntimeWarning) n_parameters = len(parameters) - return -np.infty, np.full(shape=n_parameters, fill_value=np.infty) + return -np.inf, np.full(shape=n_parameters, fill_value=np.inf) # Remember only error parameters parameters = parameters[self._n_mechanistic_params:] @@ -1606,7 +1606,7 @@ def __call__(self, parameters): 'An error occured while solving the mechanistic model: \n' + str(e) + '.\n A score of -infinity is returned.', RuntimeWarning) - return -np.infty + return -np.inf # Add noise to simulate measurements if self._error_on_log_scale: @@ -1832,7 +1832,7 @@ def evaluateS1(self, parameters): 'An error occured while solving the mechanistic model: \n' + str(e) + '.\n A score of -infinity is returned.', RuntimeWarning) - return -np.infty, sensitivities[:self._n_parameters] + return -np.inf, sensitivities[:self._n_parameters] # Add noise to simulate measurements if self._error_on_log_scale: diff --git a/chi/tests/test_inference.py b/chi/tests/test_inference.py index 5a552607..e7ef7cea 100644 --- a/chi/tests/test_inference.py +++ b/chi/tests/test_inference.py @@ -810,46 +810,6 @@ def test_run(self): self.assertEqual(runs[1], 2) self.assertEqual(runs[2], 3) - def test_run_catch_exception(self): - # Check failure of optimisation doesn't interrupt all runs - # (CMAES returns NAN for 1-dim problems) - - # Get test data and model - problem = copy.deepcopy(self.problem) - problem.fix_parameters({ - 'global.drug_concentration': 1, - 'global.kappa': 1, - 'global.lambda_0': 1, - 'global.lambda_1': 1, - 'Sigma base': 1, - 'Sigma rel.': 1}) - problem.set_log_prior(pints.ComposedLogPrior(*[ - pints.UniformLogPrior(1E-3, 1E1)])) - log_posterior = problem.get_log_posterior() - - # Set up optmisation controller - optimiser = chi.OptimisationController(log_posterior) - optimiser.set_n_runs(3) - result = optimiser.run(n_max_iterations=10) - - keys = result.keys() - self.assertEqual(len(keys), 5) - self.assertEqual(keys[0], 'ID') - self.assertEqual(keys[1], 'Parameter') - self.assertEqual(keys[2], 'Estimate') - self.assertEqual(keys[3], 'Score') - self.assertEqual(keys[4], 'Run') - - parameters = result['Parameter'].unique() - self.assertEqual(len(parameters), 1) - self.assertEqual(parameters[0], 'global.tumour_volume') - - runs = result['Run'].unique() - self.assertEqual(len(runs), 3) - self.assertEqual(runs[0], 1) - self.assertEqual(runs[1], 2) - self.assertEqual(runs[2], 3) - def test_set_optmiser(self): optimiser = chi.OptimisationController(self.log_posterior_id_40) optimiser.set_optimiser(pints.PSO) diff --git a/chi/tests/test_log_pdfs.py b/chi/tests/test_log_pdfs.py index 869d9fb6..f40b20ad 100644 --- a/chi/tests/test_log_pdfs.py +++ b/chi/tests/test_log_pdfs.py @@ -1824,7 +1824,7 @@ def test_call_and_compute_pointwise_ll(self): self.assertAlmostEqual(score, ref_score) n_obs = 7 self.assertEqual(pw_score.shape, (n_obs,)) - self.assertEqual(np.sum(pw_score), score) + self.assertAlmostEqual(np.sum(pw_score), score) # Reset number of outputs self.model.set_outputs(['central.drug_amount', 'dose.drug_amount']) diff --git a/docs/source/api/index.rst b/docs/source/api/index.rst index f5799d33..3ee66e5c 100644 --- a/docs/source/api/index.rst +++ b/docs/source/api/index.rst @@ -29,46 +29,46 @@ Summary of all functions and classes in chi .. autosummary:: - chi.AveragedPredictiveModel - chi.compute_pointwise_loglikelihood - chi.ConstantAndMultiplicativeGaussianErrorModel - chi.CovariateModel - chi.ErrorModel - chi.library.DataLibrary - chi.library.ModelLibrary - chi.LinearCovariateModel - chi.LogLikelihood - chi.LogNormalErrorModel - chi.LogNormalModel - chi.LogPosterior - chi.HeterogeneousModel - chi.HierarchicalLogLikelihood - chi.HierarchicalLogPosterior - chi.GaussianErrorModel - chi.GaussianModel - chi.InferenceController - chi.MechanisticModel - chi.MultiplicativeGaussianErrorModel - chi.OptimisationController - chi.PAMPredictiveModel - chi.PKPDModel - chi.plots.MarginalPosteriorPlot - chi.plots.ParameterEstimatePlot - chi.plots.PDTimeSeriesPlot - chi.plots.PKTimeSeriesPlot - chi.plots.PDPredictivePlot - chi.plots.PKPredictivePlot - chi.plots.ResidualPlot - chi.PooledModel - chi.PopulationModel - chi.PopulationPredictiveModel - chi.ReducedErrorModel - chi.PosteriorPredictiveModel - chi.PredictiveModel - chi.PriorPredictiveModel - chi.ProblemModellingController - chi.ReducedMechanisticModel - chi.ReducedPopulationModel - chi.SamplingController - chi.SBMLModel - chi.TruncatedGaussianModel + AveragedPredictiveModel + compute_pointwise_loglikelihood + ConstantAndMultiplicativeGaussianErrorModel + CovariateModel + ErrorModel + library.DataLibrary + library.ModelLibrary + LinearCovariateModel + LogLikelihood + LogNormalErrorModel + LogNormalModel + LogPosterior + HeterogeneousModel + HierarchicalLogLikelihood + HierarchicalLogPosterior + GaussianErrorModel + GaussianModel + InferenceController + MechanisticModel + MultiplicativeGaussianErrorModel + OptimisationController + PAMPredictiveModel + PKPDModel + plots.MarginalPosteriorPlot + plots.ParameterEstimatePlot + plots.PDTimeSeriesPlot + plots.PKTimeSeriesPlot + plots.PDPredictivePlot + plots.PKPredictivePlot + plots.ResidualPlot + PooledModel + PopulationModel + PopulationPredictiveModel + ReducedErrorModel + PosteriorPredictiveModel + PredictiveModel + PriorPredictiveModel + ProblemModellingController + ReducedMechanisticModel + ReducedPopulationModel + SamplingController + SBMLModel + TruncatedGaussianModel diff --git a/docs/source/api/mechanistic_models.rst b/docs/source/api/mechanistic_models.rst index 36ecf3b4..f6be69ad 100644 --- a/docs/source/api/mechanistic_models.rst +++ b/docs/source/api/mechanistic_models.rst @@ -9,14 +9,14 @@ Mechanistic Models Mechanistic models in chi refer to any deterministic model that describes the evolution of quantities of interest in time. In systems biology such models are often inspired by biological mechanisms, which is why we go -with the name :class:`chi.MechanisticModel`. :class:`chi.MechanisticModel` by +with the name :class:`MechanisticModel`. :class:`MechanisticModel` by no means have to be mechanism-based though, but may be any function of time that you may deem interesting. Chi provides two ways to specify mechanistic models: 1. you can use the -:class:`chi.MechanisticModel` base class an implement its methods yourself; +:class:`MechanisticModel` base class an implement its methods yourself; 2. you can specify the mechanistic model using the System Biology Markup -Language (SBML_) and instantiate the model using :class:`chi.SBMLModel`. +Language (SBML_) and instantiate the model using :class:`SBMLModel`. For detailed examples how either of those can be done, we refer to the Getting started. diff --git a/docs/source/getting_started/fitting_models_to_data.rst b/docs/source/getting_started/fitting_models_to_data.rst index 85466518..b9348032 100644 --- a/docs/source/getting_started/fitting_models_to_data.rst +++ b/docs/source/getting_started/fitting_models_to_data.rst @@ -712,15 +712,15 @@ Reference to ErrorModel, LogPDF and PredictiveModel API .. autosummary:: - chi.ErrorModel - chi.GaussianErrorModel - chi.LogNormalErrorModel - chi.MultiplicativeGaussianErrorModel - chi.ConstantAndMultiplicativeGaussianErrorModel - chi.ReducedErrorModel - chi.LogLikelihood - chi.LogPosterior - chi.ProblemModellingController - chi.SamplingController - chi.PredictiveModel - chi.PosteriorPredictiveModel \ No newline at end of file + ErrorModel + GaussianErrorModel + LogNormalErrorModel + MultiplicativeGaussianErrorModel + ConstantAndMultiplicativeGaussianErrorModel + ReducedErrorModel + LogLikelihood + LogPosterior + ProblemModellingController + SamplingController + PredictiveModel + PosteriorPredictiveModel \ No newline at end of file diff --git a/docs/source/getting_started/mechanistic_model.rst b/docs/source/getting_started/mechanistic_model.rst index b284a8ed..0ebb5e36 100644 --- a/docs/source/getting_started/mechanistic_model.rst +++ b/docs/source/getting_started/mechanistic_model.rst @@ -940,7 +940,7 @@ Reference to MechanisticModel API .. autosummary:: - chi.MechanisticModel - chi.SBMLModel - chi.PKPDModel - chi.ReducedMechanisticModel \ No newline at end of file + MechanisticModel + SBMLModel + PKPDModel + ReducedMechanisticModel \ No newline at end of file diff --git a/setup.py b/setup.py index ec56d640..a67d3ecd 100644 --- a/setup.py +++ b/setup.py @@ -9,7 +9,7 @@ setup( # Module name name='chi-drm', - version='1.0.1', + version='1.0.2', description='Package to model dose response dynamics', long_description=readme, long_description_content_type="text/markdown", @@ -30,13 +30,13 @@ # List of dependencies install_requires=[ - 'arviz>=0.11', + 'arviz>=0.17', 'myokit>=1.34', 'numpy>=1.17', 'pandas>=0.24', 'pints>=0.4', 'plotly>=4.8.1', - 'scipy<=1.12', # 07/2024 - ArviZ seems to not yet keep up with SciPy + 'scipy>=1.11', # 07/2024 - ArviZ seems to not yet keep up with SciPy 'tqdm>=4.46.1', 'xarray>=0.19', ],