From a8b277add46ab45e7e56ecffe43cf39da1bd231b Mon Sep 17 00:00:00 2001 From: sdromigny <147389807+sdromigny@users.noreply.github.com> Date: Wed, 18 Oct 2023 10:23:54 +0100 Subject: [PATCH 01/27] Create new_branch --- new_branch | 1 + 1 file changed, 1 insertion(+) create mode 100644 new_branch diff --git a/new_branch b/new_branch new file mode 100644 index 0000000..718f4d2 --- /dev/null +++ b/new_branch @@ -0,0 +1 @@ +t From 9b667a9e729290e1bdb8c8f3dc8f7f3e48b6428f Mon Sep 17 00:00:00 2001 From: Sixtine Dromigny Date: Wed, 18 Oct 2023 12:08:21 +0100 Subject: [PATCH 02/27] add 2 functions for the 2 PK models : intravenous IV and subcutaneous SC for #7 and #11 --- prototype.py | 56 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 43 insertions(+), 13 deletions(-) diff --git a/prototype.py b/prototype.py index 96b0083..1dfdfde 100644 --- a/prototype.py +++ b/prototype.py @@ -5,7 +5,9 @@ def dose(t, X): return X -def rhs(t, y, Q_p1, V_c, V_p1, CL, X): +#intravenous injection model + +def IV(t, y, Q_p1, V_c, V_p1, CL, X): q_c, q_p1 = y transition = Q_p1 * (q_c / V_c - q_p1 / V_p1) dqc_dt = dose(t, X) - q_c / V_c * CL - transition @@ -21,6 +23,16 @@ def rhs(t, y, Q_p1, V_c, V_p1, CL, X): 'X': 1.0, } +#subcutaneous dosing +def SC(t, y, Q_p1, V_c, V_p1, CL, X, ka): + q_c, q_p1, q0= y + dq0_dt = dose(t,X) - ka*q0 + transition = Q_p1 * (q_c / V_c - q_p1 / V_p1) + dqc_dt = ka*q0 - q_c / V_c * CL - transition + dqp1_dt = transition + return [dqc_dt, dqp1_dt,dq0_dt] + + model2_args = { 'name': 'model2', 'Q_p1': 2.0, @@ -28,25 +40,43 @@ def rhs(t, y, Q_p1, V_c, V_p1, CL, X): 'V_p1': 1.0, 'CL': 1.0, 'X': 1.0, + 'ka':1.0 } t_eval = np.linspace(0, 1, 1000) y0 = np.array([0.0, 0.0]) fig = plt.figure() -for model in [model1_args, model2_args]: - args = [ - model['Q_p1'], model['V_c'], model['V_p1'], model['CL'], model['X'] - ] - sol = scipy.integrate.solve_ivp( - fun=lambda t, y: rhs(t, y, *args), - t_span=[t_eval[0], t_eval[-1]], - y0=y0, t_eval=t_eval - ) - plt.plot(sol.t, sol.y[0, :], label=model['name'] + '- q_c') - plt.plot(sol.t, sol.y[1, :], label=model['name'] + '- q_p1') + +args = [ + model1_args['Q_p1'], model1_args['V_c'], model1_args['V_p1'], model1_args['CL'], model1_args['X'] +] +sol = scipy.integrate.solve_ivp( + fun=lambda t, y: IV(t, y, *args), + t_span=[t_eval[0], t_eval[-1]], + y0=y0, t_eval=t_eval +) +plt.plot(sol.t, sol.y[0, :], label=model1_args['name'] + '- q_c') +plt.plot(sol.t, sol.y[1, :], label=model1_args['name'] + '- q_p1') + + + +y0 = np.array([0.0, 0.0, 0.0]) + +args = [ + model2_args['Q_p1'], model2_args['V_c'], model2_args['V_p1'], model2_args['CL'], model2_args['X'], model2_args['ka'] +] +sol = scipy.integrate.solve_ivp( + fun=lambda t, y: SC(t, y, *args), + t_span=[t_eval[0], t_eval[-1]], + y0=y0, t_eval=t_eval +) +plt.plot(sol.t, sol.y[0, :], label=model2_args['name'] + '- q_c') +plt.plot(sol.t, sol.y[1, :], label=model2_args['name'] + '- q_p1') plt.legend() plt.ylabel('drug mass [ng]') plt.xlabel('time [h]') -plt.show() + +plt.savefig('plot.png') + From e85b08d1157d949dc0e820177cfdf862556ff22a Mon Sep 17 00:00:00 2001 From: Robert Doane-Solomon Date: Wed, 18 Oct 2023 15:30:43 +0100 Subject: [PATCH 03/27] committing codecov file --- workflows/basic.yml | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 workflows/basic.yml diff --git a/workflows/basic.yml b/workflows/basic.yml new file mode 100644 index 0000000..10746c2 --- /dev/null +++ b/workflows/basic.yml @@ -0,0 +1,39 @@ +name: Coverage + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + workflow_dispatch: + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + + - uses: actions/checkout@v3 + + - name: Set up Python 3.10 + uses: actions/setup-python@v3 + with: + python-version: "3.10" + + - name: Install dependencies + run: | + python -m pip install --upgrade pip setuptools wheel + python -m pip install .[dev] + + - name: Run coverage + run: | + pytest --cov-config=.coveragerc --cov=./ci_course --cov-report=xml + cat coverage.xml + + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v3 + with: + token: ${{ secrets.CODECOV_TOKEN }} + fail_ci_if_error: true + files: coverage.xml From 53ae6fb8ca02c7f3a80cfe88e6b229d7d0fb4699 Mon Sep 17 00:00:00 2001 From: Robert Doane-Solomon Date: Wed, 18 Oct 2023 15:38:07 +0100 Subject: [PATCH 04/27] committing basic.yml for codecov --- workflows/basic.yml | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 workflows/basic.yml diff --git a/workflows/basic.yml b/workflows/basic.yml new file mode 100644 index 0000000..10746c2 --- /dev/null +++ b/workflows/basic.yml @@ -0,0 +1,39 @@ +name: Coverage + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + workflow_dispatch: + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + + - uses: actions/checkout@v3 + + - name: Set up Python 3.10 + uses: actions/setup-python@v3 + with: + python-version: "3.10" + + - name: Install dependencies + run: | + python -m pip install --upgrade pip setuptools wheel + python -m pip install .[dev] + + - name: Run coverage + run: | + pytest --cov-config=.coveragerc --cov=./ci_course --cov-report=xml + cat coverage.xml + + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v3 + with: + token: ${{ secrets.CODECOV_TOKEN }} + fail_ci_if_error: true + files: coverage.xml From d67f4ab9ba957b7cd877d7331a8d675346a8c262 Mon Sep 17 00:00:00 2001 From: robertdoanesolomon Date: Wed, 18 Oct 2023 15:43:37 +0100 Subject: [PATCH 05/27] Update basic.yml --- workflows/basic.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflows/basic.yml b/workflows/basic.yml index 10746c2..1445326 100644 --- a/workflows/basic.yml +++ b/workflows/basic.yml @@ -28,7 +28,7 @@ jobs: - name: Run coverage run: | - pytest --cov-config=.coveragerc --cov=./ci_course --cov-report=xml + pytest --cov-config=.coveragerc --cov=. --cov-report=xml cat coverage.xml - name: Upload coverage reports to Codecov From 2f4cb5dd31d4b71e8530715ce384fded09b365fa Mon Sep 17 00:00:00 2001 From: robertdoanesolomon Date: Wed, 18 Oct 2023 15:55:06 +0100 Subject: [PATCH 06/27] Update basic.yml --- workflows/basic.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflows/basic.yml b/workflows/basic.yml index 1445326..f7d3129 100644 --- a/workflows/basic.yml +++ b/workflows/basic.yml @@ -28,7 +28,7 @@ jobs: - name: Run coverage run: | - pytest --cov-config=.coveragerc --cov=. --cov-report=xml + pytest --cov-config=.coveragerc --cov=. --cov-report=xml --cov-branch cat coverage.xml - name: Upload coverage reports to Codecov From fcaac26d8503618f00c8e31fc6ce143725b9d05e Mon Sep 17 00:00:00 2001 From: robertdoanesolomon Date: Wed, 18 Oct 2023 15:56:41 +0100 Subject: [PATCH 07/27] Update basic.yml --- workflows/basic.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/workflows/basic.yml b/workflows/basic.yml index f7d3129..f80cf93 100644 --- a/workflows/basic.yml +++ b/workflows/basic.yml @@ -2,9 +2,9 @@ name: Coverage on: push: - branches: [ "main" ] + branches: [ "dev" ] pull_request: - branches: [ "main" ] + branches: [ "dev" ] workflow_dispatch: jobs: From a220a41890826024b46af6cacd68ab2e56dc94ae Mon Sep 17 00:00:00 2001 From: Robert Doane-Solomon Date: Wed, 18 Oct 2023 16:01:44 +0100 Subject: [PATCH 08/27] testing --- test.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 test.txt diff --git a/test.txt b/test.txt new file mode 100644 index 0000000..616f5ec --- /dev/null +++ b/test.txt @@ -0,0 +1 @@ +"hi" From 9b9ae29e960d20958da74f749baab2860df25500 Mon Sep 17 00:00:00 2001 From: robertdoanesolomon Date: Wed, 18 Oct 2023 16:03:54 +0100 Subject: [PATCH 09/27] Update basic.yml --- workflows/basic.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflows/basic.yml b/workflows/basic.yml index f80cf93..6840746 100644 --- a/workflows/basic.yml +++ b/workflows/basic.yml @@ -28,7 +28,7 @@ jobs: - name: Run coverage run: | - pytest --cov-config=.coveragerc --cov=. --cov-report=xml --cov-branch + pytest --cov-config=.coveragerc --cov=./pkmodel --cov-report=xml --cov-branch cat coverage.xml - name: Upload coverage reports to Codecov From f8831408ff26428f2e77f3611af14999c1e0ddeb Mon Sep 17 00:00:00 2001 From: Robert Doane-Solomon Date: Wed, 18 Oct 2023 16:11:11 +0100 Subject: [PATCH 10/27] committing codecov thing --- .github/workflows/basic.yml | 39 +++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 .github/workflows/basic.yml diff --git a/.github/workflows/basic.yml b/.github/workflows/basic.yml new file mode 100644 index 0000000..6840746 --- /dev/null +++ b/.github/workflows/basic.yml @@ -0,0 +1,39 @@ +name: Coverage + +on: + push: + branches: [ "dev" ] + pull_request: + branches: [ "dev" ] + workflow_dispatch: + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + + - uses: actions/checkout@v3 + + - name: Set up Python 3.10 + uses: actions/setup-python@v3 + with: + python-version: "3.10" + + - name: Install dependencies + run: | + python -m pip install --upgrade pip setuptools wheel + python -m pip install .[dev] + + - name: Run coverage + run: | + pytest --cov-config=.coveragerc --cov=./pkmodel --cov-report=xml --cov-branch + cat coverage.xml + + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v3 + with: + token: ${{ secrets.CODECOV_TOKEN }} + fail_ci_if_error: true + files: coverage.xml From 40c8c2e2d27b76073ccb1d0c3ac5f5450335c503 Mon Sep 17 00:00:00 2001 From: robertdoanesolomon Date: Wed, 18 Oct 2023 16:16:04 +0100 Subject: [PATCH 11/27] Update test_model.py --- pkmodel/tests/test_model.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkmodel/tests/test_model.py b/pkmodel/tests/test_model.py index 274ba9c..a847eb3 100644 --- a/pkmodel/tests/test_model.py +++ b/pkmodel/tests/test_model.py @@ -1,6 +1,7 @@ import unittest import pkmodel as pk - +import pytest +import pytest-cov class ModelTest(unittest.TestCase): """ From 255b77bed41a49eaee72981b72b584c4fb0d6966 Mon Sep 17 00:00:00 2001 From: Tristram Walsh Date: Wed, 18 Oct 2023 16:18:16 +0100 Subject: [PATCH 12/27] Remove old test files. --- new_branch | 1 - test.txt | 1 - 2 files changed, 2 deletions(-) delete mode 100644 new_branch delete mode 100644 test.txt diff --git a/new_branch b/new_branch deleted file mode 100644 index 718f4d2..0000000 --- a/new_branch +++ /dev/null @@ -1 +0,0 @@ -t diff --git a/test.txt b/test.txt deleted file mode 100644 index 616f5ec..0000000 --- a/test.txt +++ /dev/null @@ -1 +0,0 @@ -"hi" From 91a5a1bc3493d5fad1a790a764eb458390281ed0 Mon Sep 17 00:00:00 2001 From: robertdoanesolomon Date: Wed, 18 Oct 2023 16:18:59 +0100 Subject: [PATCH 13/27] Update basic.yml --- .github/workflows/basic.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/basic.yml b/.github/workflows/basic.yml index 6840746..2d674c8 100644 --- a/.github/workflows/basic.yml +++ b/.github/workflows/basic.yml @@ -25,6 +25,8 @@ jobs: run: | python -m pip install --upgrade pip setuptools wheel python -m pip install .[dev] + python -m pip install pytest + python -m pip install pytest-cov - name: Run coverage run: | From 52a8f183609e51e491ff73772ff2ec02d19bfddd Mon Sep 17 00:00:00 2001 From: robertdoanesolomon Date: Wed, 18 Oct 2023 16:20:47 +0100 Subject: [PATCH 14/27] Update test_model.py --- pkmodel/tests/test_model.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/pkmodel/tests/test_model.py b/pkmodel/tests/test_model.py index a847eb3..4b1a528 100644 --- a/pkmodel/tests/test_model.py +++ b/pkmodel/tests/test_model.py @@ -1,7 +1,5 @@ import unittest import pkmodel as pk -import pytest -import pytest-cov class ModelTest(unittest.TestCase): """ From 4a63c0ea990b5e25e6812111e0054da9b6fbe1c7 Mon Sep 17 00:00:00 2001 From: Tristram Walsh Date: Wed, 18 Oct 2023 16:36:33 +0100 Subject: [PATCH 15/27] Add basic pyproject.toml for setuptools, and comment out all code in legacy setup.py. See issue #1. --- pyproject.toml | 31 +++++++++++++ setup.py | 120 ++++++++++++++++++++++++------------------------- 2 files changed, 91 insertions(+), 60 deletions(-) create mode 100644 pyproject.toml diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..3f00f5c --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,31 @@ +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" + +[project] +name = "pkmodel" +version = "0.0.1" +authors = [ + { name="Rhiannon Ackland, email="author@example.com" }, + { name="Sarah Bull, email="author@example.com" }, + { name="Sixtine Dromigny, email="author@example.com" }, + { name="Robert Doane-Solomon, email="author@example.com" }, + { name="Tristram Walsh, email="author@example.com" }, + ] +description = "pkmodel is a Pharmokinetic modelling library." +readme = "README.md" +classifiers = [ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: MIT License", + "Operating System :: Linux", +] +dependencies =[ + 'numpy', + 'matplotlib', + 'scipy', + 'pytest', +] + +[project.urls] +"Homepage" = "https://github.com/robertdoanesolomon/software-engineering-projects-pk" +"Bug Tracker" = "https://github.com/robertdoanesolomon/software-engineering-projects-pk/issues" \ No newline at end of file diff --git a/setup.py b/setup.py index e35b8c8..3325b19 100644 --- a/setup.py +++ b/setup.py @@ -1,80 +1,80 @@ -# -# pkmodel setuptools script -# -from setuptools import setup, find_packages +# # +# # pkmodel setuptools script +# # +# from setuptools import setup, find_packages -def get_version(): - """ - Get version number from the pkmodel module. +# def get_version(): +# """ +# Get version number from the pkmodel module. - The easiest way would be to just ``import pkmodel ``, but note that this may - fail if the dependencies have not been installed yet. Instead, we've put - the version number in a simple version_info module, that we'll import here - by temporarily adding the oxrse directory to the pythonpath using sys.path. - """ - import os - import sys +# The easiest way would be to just ``import pkmodel ``, but note that this may +# fail if the dependencies have not been installed yet. Instead, we've put +# the version number in a simple version_info module, that we'll import here +# by temporarily adding the oxrse directory to the pythonpath using sys.path. +# """ +# import os +# import sys - sys.path.append(os.path.abspath('pkmodel')) - from version_info import VERSION as version - sys.path.pop() +# sys.path.append(os.path.abspath('pkmodel')) +# from version_info import VERSION as version +# sys.path.pop() - return version +# return version -def get_readme(): - """ - Load README.md text for use as description. - """ - with open('README.md') as f: - return f.read() +# def get_readme(): +# """ +# Load README.md text for use as description. +# """ +# with open('README.md') as f: +# return f.read() -# Go! -setup( - # Module name (lowercase) - name='pkmodel', +# # Go! +# setup( +# # Module name (lowercase) +# name='pkmodel', - # Version - version=get_version(), +# # Version +# version=get_version(), - description='An example Python project.', +# description='An example Python project.', - long_description=get_readme(), +# long_description=get_readme(), - license='MIT license', +# license='MIT license', - # author='', +# # author='', - # author_email='', +# # author_email='', - maintainer='Martin Robinson', +# maintainer='Martin Robinson', - maintainer_email='martin.robinson@cs.ox.ac.uk', +# maintainer_email='martin.robinson@cs.ox.ac.uk', - url='https://github.com/SABS-R3/2020-software-engineering-projects-pk', +# url='https://github.com/SABS-R3/2020-software-engineering-projects-pk', - # Packages to include - packages=find_packages(include=('pkmodel', 'pkmodel.*')), +# # Packages to include +# packages=find_packages(include=('pkmodel', 'pkmodel.*')), - # List of dependencies - install_requires=[ - # Dependencies go here! - 'numpy', - 'matplotlib', - 'scipy', - ], - extras_require={ - 'docs': [ - # Sphinx for doc generation. Version 1.7.3 has a bug: - 'sphinx>=1.5, !=1.7.3', - # Nice theme for docs - 'sphinx_rtd_theme', - ], - 'dev': [ - # Flake8 for code style checking - 'flake8>=3', - ], - }, -) +# # List of dependencies +# install_requires=[ +# # Dependencies go here! +# 'numpy', +# 'matplotlib', +# 'scipy', +# ], +# extras_require={ +# 'docs': [ +# # Sphinx for doc generation. Version 1.7.3 has a bug: +# 'sphinx>=1.5, !=1.7.3', +# # Nice theme for docs +# 'sphinx_rtd_theme', +# ], +# 'dev': [ +# # Flake8 for code style checking +# 'flake8>=3', +# ], +# }, +# ) From c22ad8f06ee98df4dc0610f45534cd93ed6779b5 Mon Sep 17 00:00:00 2001 From: Tristram Walsh Date: Thu, 19 Oct 2023 09:53:59 +0100 Subject: [PATCH 16/27] Change name of continuous integration branch to 'master' instead of 'main', which we don't have. Issue #6. --- workflows/basic.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/workflows/basic.yml b/workflows/basic.yml index 10746c2..3bf2c48 100644 --- a/workflows/basic.yml +++ b/workflows/basic.yml @@ -2,9 +2,9 @@ name: Coverage on: push: - branches: [ "main" ] + branches: [ "master" ] pull_request: - branches: [ "main" ] + branches: [ "master" ] workflow_dispatch: jobs: From 21c008ace24714f3f577afdc7a9d0fa4398ec122 Mon Sep 17 00:00:00 2001 From: Tristram Walsh Date: Thu, 19 Oct 2023 10:12:29 +0100 Subject: [PATCH 17/27] Minimal working installable package structure. src/package structure introduced to avoid ambiguity errors in installation owing to multiple top-level directories in the package. --- pyproject.toml | 10 +-- setup.py | 80 ----------------------- {pkmodel => src/pkmodel}/__init__.py | 0 {pkmodel => src/pkmodel}/model.py | 0 {pkmodel => src/pkmodel}/protocol.py | 0 {pkmodel => src/pkmodel}/solution.py | 0 {pkmodel => src/pkmodel}/version_info.py | 0 {pkmodel/tests => tests}/__init__.py | 0 {pkmodel/tests => tests}/test_model.py | 0 {pkmodel/tests => tests}/test_protocol.py | 0 {pkmodel/tests => tests}/test_solution.py | 0 11 files changed, 5 insertions(+), 85 deletions(-) delete mode 100644 setup.py rename {pkmodel => src/pkmodel}/__init__.py (100%) rename {pkmodel => src/pkmodel}/model.py (100%) rename {pkmodel => src/pkmodel}/protocol.py (100%) rename {pkmodel => src/pkmodel}/solution.py (100%) rename {pkmodel => src/pkmodel}/version_info.py (100%) rename {pkmodel/tests => tests}/__init__.py (100%) rename {pkmodel/tests => tests}/test_model.py (100%) rename {pkmodel/tests => tests}/test_protocol.py (100%) rename {pkmodel/tests => tests}/test_solution.py (100%) diff --git a/pyproject.toml b/pyproject.toml index 3f00f5c..0e8bab6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,11 +6,11 @@ build-backend = "setuptools.build_meta" name = "pkmodel" version = "0.0.1" authors = [ - { name="Rhiannon Ackland, email="author@example.com" }, - { name="Sarah Bull, email="author@example.com" }, - { name="Sixtine Dromigny, email="author@example.com" }, - { name="Robert Doane-Solomon, email="author@example.com" }, - { name="Tristram Walsh, email="author@example.com" }, + { name="Rhiannon Ackland", email="author@example.com" }, + { name="Sarah Bull", email="author@example.com" }, + { name="Sixtine Dromigny", email="author@example.com" }, + { name="Robert Doane-Solomon", email="author@example.com" }, + { name="Tristram Walsh", email="author@example.com" }, ] description = "pkmodel is a Pharmokinetic modelling library." readme = "README.md" diff --git a/setup.py b/setup.py deleted file mode 100644 index 3325b19..0000000 --- a/setup.py +++ /dev/null @@ -1,80 +0,0 @@ -# # -# # pkmodel setuptools script -# # -# from setuptools import setup, find_packages - - -# def get_version(): -# """ -# Get version number from the pkmodel module. - -# The easiest way would be to just ``import pkmodel ``, but note that this may -# fail if the dependencies have not been installed yet. Instead, we've put -# the version number in a simple version_info module, that we'll import here -# by temporarily adding the oxrse directory to the pythonpath using sys.path. -# """ -# import os -# import sys - -# sys.path.append(os.path.abspath('pkmodel')) -# from version_info import VERSION as version -# sys.path.pop() - -# return version - - -# def get_readme(): -# """ -# Load README.md text for use as description. -# """ -# with open('README.md') as f: -# return f.read() - - -# # Go! -# setup( -# # Module name (lowercase) -# name='pkmodel', - -# # Version -# version=get_version(), - -# description='An example Python project.', - -# long_description=get_readme(), - -# license='MIT license', - -# # author='', - -# # author_email='', - -# maintainer='Martin Robinson', - -# maintainer_email='martin.robinson@cs.ox.ac.uk', - -# url='https://github.com/SABS-R3/2020-software-engineering-projects-pk', - -# # Packages to include -# packages=find_packages(include=('pkmodel', 'pkmodel.*')), - -# # List of dependencies -# install_requires=[ -# # Dependencies go here! -# 'numpy', -# 'matplotlib', -# 'scipy', -# ], -# extras_require={ -# 'docs': [ -# # Sphinx for doc generation. Version 1.7.3 has a bug: -# 'sphinx>=1.5, !=1.7.3', -# # Nice theme for docs -# 'sphinx_rtd_theme', -# ], -# 'dev': [ -# # Flake8 for code style checking -# 'flake8>=3', -# ], -# }, -# ) diff --git a/pkmodel/__init__.py b/src/pkmodel/__init__.py similarity index 100% rename from pkmodel/__init__.py rename to src/pkmodel/__init__.py diff --git a/pkmodel/model.py b/src/pkmodel/model.py similarity index 100% rename from pkmodel/model.py rename to src/pkmodel/model.py diff --git a/pkmodel/protocol.py b/src/pkmodel/protocol.py similarity index 100% rename from pkmodel/protocol.py rename to src/pkmodel/protocol.py diff --git a/pkmodel/solution.py b/src/pkmodel/solution.py similarity index 100% rename from pkmodel/solution.py rename to src/pkmodel/solution.py diff --git a/pkmodel/version_info.py b/src/pkmodel/version_info.py similarity index 100% rename from pkmodel/version_info.py rename to src/pkmodel/version_info.py diff --git a/pkmodel/tests/__init__.py b/tests/__init__.py similarity index 100% rename from pkmodel/tests/__init__.py rename to tests/__init__.py diff --git a/pkmodel/tests/test_model.py b/tests/test_model.py similarity index 100% rename from pkmodel/tests/test_model.py rename to tests/test_model.py diff --git a/pkmodel/tests/test_protocol.py b/tests/test_protocol.py similarity index 100% rename from pkmodel/tests/test_protocol.py rename to tests/test_protocol.py diff --git a/pkmodel/tests/test_solution.py b/tests/test_solution.py similarity index 100% rename from pkmodel/tests/test_solution.py rename to tests/test_solution.py From ab9b084b2d53acd47777d31cabf7c874b58a98de Mon Sep 17 00:00:00 2001 From: Sixtine Dromigny Date: Thu, 19 Oct 2023 10:51:36 +0100 Subject: [PATCH 18/27] updated model.p but still not working (issue #7 and #15) --- new_branch | 1 - pkmodel/model.py | 85 ++++++++++++++++++++++++++++++++++++++++++++- pkmodel/solution.py | 39 +++++++++++++++++++++ 3 files changed, 123 insertions(+), 2 deletions(-) delete mode 100644 new_branch diff --git a/new_branch b/new_branch deleted file mode 100644 index 718f4d2..0000000 --- a/new_branch +++ /dev/null @@ -1 +0,0 @@ -t diff --git a/pkmodel/model.py b/pkmodel/model.py index 1b5fd40..03439da 100644 --- a/pkmodel/model.py +++ b/pkmodel/model.py @@ -1,6 +1,9 @@ # # Model class # +import matplotlib.pylab as plt +import numpy as np +import scipy.integrate class Model: """A Pharmokinetic (PK) model @@ -13,5 +16,85 @@ class Model: """ def __init__(self, value=42): - self.value = value + self.value = value +class IV(Model): + "intraveinous model : : calls parent class Model" + def __init__(self, args=[0, 0, 0, 0, 0]): + super().__init__() + self.args=args + + def dose(self, t, X): + return X + + #def IV(self, t, y, Q_p1, V_c, V_p1, CL, X): + def param(self, t, y, Q_p1, V_c, V_p1, CL, X): + q_c, q_p1 = y + transition = Q_p1 * (q_c / V_c - q_p1 / V_p1) + dqc_dt = self.dose(t, X) - q_c / V_c * CL - transition + dqp1_dt = transition + return [dqc_dt, dqp1_dt] + + # def integrate(self, Q_p1, V_c, V_p1, CL, X): + # t_eval = np.linspace(0, 1, 1000) + # y0 = np.array([0.0, 0.0]) + # sol = scipy.integrate.solve_ivp( + # fun=lambda t, y: self.param(t, y, Q_p1, V_c, V_p1, CL, X), + # t_span=[t_eval[0], t_eval[-1]], + # y0=y0, + # t_eval=t_eval) + # return sol + +# iv_model = IV() +# solution = iv_model.integrate(1,2,3,4,5) +# print(solution) + +t_eval = np.linspace(0, 1, 1000) +y0 = np.array([0.0, 0.0]) +sol = scipy.integrate.solve_ivp( + fun=lambda t, y: IV.param(self, t, y, 1, 2, 3, 4, 5), + t_span=[t_eval[0], t_eval[-1]], + y0=y0, + t_eval=t_eval) + +print(sol) + + +model1_args = { + 'name': 'model1', + 'Q_p1': 1.0, + 'V_c': 1.0, + 'V_p1': 1.0, + 'CL': 1.0, + 'X': 1.0,} + +class SC(Model): + "subcutaneous model" + def __init__(self, name): + super().__init__(name) + #self.observations = [] + + def dose(self, t, X): + return X + + #def SC(self, t, y, Q_p1, V_c, V_p1, CL, X, ka): + def SC(self, t, y, *args): + q_c, q_p1, q0= y + dq0_dt = dose(t,X) - ka*q0 + transition = Q_p1 * (q_c / V_c - q_p1 / V_p1) + dqc_dt = ka*q0 - q_c / V_c * CL - transition + dqp1_dt = transition + return [dqc_dt, dqp1_dt,dq0_dt] + + model2_args = { + 'name': 'model2', + 'Q_p1': 0, + 'V_c': 0, + 'V_p1': 0, + 'CL': 0, + 'X': 0, + 'ka': 0} + + + +### how to make scipy y integration value connected with the visualisation/solution class which acitvely uses scipy \ No newline at end of file diff --git a/pkmodel/solution.py b/pkmodel/solution.py index d08710b..7dbd29e 100644 --- a/pkmodel/solution.py +++ b/pkmodel/solution.py @@ -14,4 +14,43 @@ class Solution: """ def __init__(self, value=44): self.value = value + def plot(): + t_eval = np.linspace(0, 1, 1000) + y0 = np.array([0.0, 0.0]) + + fig = plt.figure() + + args = [ + model1_args['Q_p1'], model1_args['V_c'], model1_args['V_p1'], model1_args['CL'], model1_args['X'] + ] + sol = scipy.integrate.solve_ivp( + fun=lambda t, y: IV(t, y, *args), + t_span=[t_eval[0], t_eval[-1]], + y0=y0, t_eval=t_eval + ) + plt.plot(sol.t, sol.y[0, :], label=model1_args['name'] + '- q_c') + plt.plot(sol.t, sol.y[1, :], label=model1_args['name'] + '- q_p1') + + + + y0 = np.array([0.0, 0.0, 0.0]) + + args = [ + model2_args['Q_p1'], model2_args['V_c'], model2_args['V_p1'], model2_args['CL'], model2_args['X'], model2_args['ka'] + ] + sol = scipy.integrate.solve_ivp( + fun=lambda t, y: SC(t, y, *args), + t_span=[t_eval[0], t_eval[-1]], + y0=y0, t_eval=t_eval + ) + plt.plot(sol.t, sol.y[0, :], label=model2_args['name'] + '- q_c') + plt.plot(sol.t, sol.y[1, :], label=model2_args['name'] + '- q_p1') + + plt.legend() + plt.ylabel('drug mass [ng]') + plt.xlabel('time [h]') + + plt.savefig('plot.png') + +## package importing From 1c6e4dc5f15e65b4f6ac8a3efcf1e88c1066d66e Mon Sep 17 00:00:00 2001 From: Sixtine Dromigny Date: Thu, 19 Oct 2023 12:16:07 +0100 Subject: [PATCH 19/27] parametreisation works, nowI just need to write function for integration, god be with me (issue #7 and #15) --- pkmodel/model.py | 114 +++++++++++++++++++++++++---------------------- prototype.py | 2 +- 2 files changed, 61 insertions(+), 55 deletions(-) diff --git a/pkmodel/model.py b/pkmodel/model.py index 03439da..de51173 100644 --- a/pkmodel/model.py +++ b/pkmodel/model.py @@ -4,6 +4,7 @@ import matplotlib.pylab as plt import numpy as np import scipy.integrate +from scipy.integrate import odeint class Model: """A Pharmokinetic (PK) model @@ -19,82 +20,87 @@ def __init__(self, value=42): self.value = value class IV(Model): - "intraveinous model : : calls parent class Model" - def __init__(self, args=[0, 0, 0, 0, 0]): + # Your class definition here + def __init__(self, parameters=[0, 0, 0, 0, 0]): super().__init__() - self.args=args + self.parameters = parameters - def dose(self, t, X): - return X - - #def IV(self, t, y, Q_p1, V_c, V_p1, CL, X): - def param(self, t, y, Q_p1, V_c, V_p1, CL, X): + def param(self, y, t): + Q_p1, V_c, V_p1, CL, X = self.parameters q_c, q_p1 = y transition = Q_p1 * (q_c / V_c - q_p1 / V_p1) - dqc_dt = self.dose(t, X) - q_c / V_c * CL - transition + dqc_dt = X - q_c / V_c * CL - transition dqp1_dt = transition return [dqc_dt, dqp1_dt] - # def integrate(self, Q_p1, V_c, V_p1, CL, X): - # t_eval = np.linspace(0, 1, 1000) - # y0 = np.array([0.0, 0.0]) - # sol = scipy.integrate.solve_ivp( - # fun=lambda t, y: self.param(t, y, Q_p1, V_c, V_p1, CL, X), - # t_span=[t_eval[0], t_eval[-1]], - # y0=y0, - # t_eval=t_eval) - # return sol -# iv_model = IV() -# solution = iv_model.integrate(1,2,3,4,5) -# print(solution) +# Create an instance of the IV class +iv_instance = IV() +# Define the time points at which you want to evaluate the solution t_eval = np.linspace(0, 1, 1000) -y0 = np.array([0.0, 0.0]) -sol = scipy.integrate.solve_ivp( - fun=lambda t, y: IV.param(self, t, y, 1, 2, 3, 4, 5), - t_span=[t_eval[0], t_eval[-1]], - y0=y0, - t_eval=t_eval) -print(sol) +# Initial conditions +y0 = [0.0, 0.0] +# Parameters +parameters = [0.7, 1, 2, 3, 4] + +# Set the parameters in the instance +iv_instance.parameters = parameters + +# Solve the ODEs using odeint +solution = odeint(iv_instance.param, y0, t_eval) + +# Extract the results +q_c, q_p1 = solution.T + +# Print the results +print(q_c) +print(q_p1) -model1_args = { - 'name': 'model1', - 'Q_p1': 1.0, - 'V_c': 1.0, - 'V_p1': 1.0, - 'CL': 1.0, - 'X': 1.0,} class SC(Model): "subcutaneous model" - def __init__(self, name): - super().__init__(name) - #self.observations = [] - - def dose(self, t, X): - return X + def __init__(self, parameters=[0, 0, 0, 0, 0,0]): + super().__init__() + self.parameters = parameters - #def SC(self, t, y, Q_p1, V_c, V_p1, CL, X, ka): - def SC(self, t, y, *args): + def param(self, y, t): + Q_p1, V_c, V_p1, CL, X, ka = self.parameters q_c, q_p1, q0= y - dq0_dt = dose(t,X) - ka*q0 + dq0_dt = X - ka*q0 transition = Q_p1 * (q_c / V_c - q_p1 / V_p1) dqc_dt = ka*q0 - q_c / V_c * CL - transition dqp1_dt = transition return [dqc_dt, dqp1_dt,dq0_dt] - - model2_args = { - 'name': 'model2', - 'Q_p1': 0, - 'V_c': 0, - 'V_p1': 0, - 'CL': 0, - 'X': 0, - 'ka': 0} +# Create an instance of the IV class +sc_instance = SC() + +# Define the time points at which you want to evaluate the solution +t_eval = np.linspace(0, 1, 1000) + +# Initial conditions +y0 = [0.0, 0.0,0] + +# Parameters +parameters = [0.7, 1, 2, 3, 4,7] + +# Set the parameters in the instance +sc_instance.parameters = parameters + +# Solve the ODEs using odeint +solution = odeint(sc_instance.param, y0, t_eval) + +print(solution.shape) + +# Extract the results +print(solution.T.shape) +q_c, q_p1, q_0 = solution.T -### how to make scipy y integration value connected with the visualisation/solution class which acitvely uses scipy \ No newline at end of file +# Print the results +print(q_c.shape) +print(q_p1.shape) +print(solution.y[0, :]) diff --git a/prototype.py b/prototype.py index 1dfdfde..789179d 100644 --- a/prototype.py +++ b/prototype.py @@ -13,7 +13,7 @@ def IV(t, y, Q_p1, V_c, V_p1, CL, X): dqc_dt = dose(t, X) - q_c / V_c * CL - transition dqp1_dt = transition return [dqc_dt, dqp1_dt] - +print(IV(2,[1,2],3,4,5,6,7)) model1_args = { 'name': 'model1', 'Q_p1': 1.0, From 31dc31f6cfc9e62ae529fdfc444430d93a5a0632 Mon Sep 17 00:00:00 2001 From: Robert Doane-Solomon Date: Thu, 19 Oct 2023 12:25:12 +0100 Subject: [PATCH 20/27] upl --- pkmodel/solution.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/pkmodel/solution.py b/pkmodel/solution.py index 7dbd29e..c196798 100644 --- a/pkmodel/solution.py +++ b/pkmodel/solution.py @@ -52,5 +52,29 @@ def plot(): plt.savefig('plot.png') + +import numpy as np +import matplotlib.pyplot as plt +t_eval = np.linspace(0,10,100) +q_c = t_eval +2 +q_p1 = t_eval +3 + +def visualise(t_eval, q_c, q_p1): + fig, ax = plt.subplots() + #plt.plot(t_eval, q_c, label=Model.name + '- q_c') + #plt.plot(t_eval, q_p1, label=Model.name + '- q_p1') + ax.plot(t_eval, q_c) + ax.plot(t_eval, q_p1) + #plt.legend() + ax.set_ylabel('drug mass (ng)') + ax.set_xlabel('time [h]') + + plt.show() + return fig + +visualise(t_eval, q_c, q_p1) + + + ## package importing From e076bb08b5be5a91227745eb5883e2a1d1ec9694 Mon Sep 17 00:00:00 2001 From: Robert Doane-Solomon Date: Thu, 19 Oct 2023 12:25:31 +0100 Subject: [PATCH 21/27] git uncommit From 98ef1dd884d64ec9297b15da3c98b925e66f50d3 Mon Sep 17 00:00:00 2001 From: Robert Doane-Solomon Date: Thu, 19 Oct 2023 12:28:32 +0100 Subject: [PATCH 22/27] uploading plot code --- pkmodel/solution.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkmodel/solution.py b/pkmodel/solution.py index c196798..3f2cad7 100644 --- a/pkmodel/solution.py +++ b/pkmodel/solution.py @@ -56,7 +56,7 @@ def plot(): import numpy as np import matplotlib.pyplot as plt t_eval = np.linspace(0,10,100) -q_c = t_eval +2 +q_c = t_eval +20 q_p1 = t_eval +3 def visualise(t_eval, q_c, q_p1): From 837af9289cfba69dd732a4209dc420c45146a7f7 Mon Sep 17 00:00:00 2001 From: Tristram Walsh Date: Thu, 19 Oct 2023 13:13:46 +0100 Subject: [PATCH 23/27] Update path to package for continuous integration, to be aligned with directory structure as in branch - see issues #1 and #6. --- workflows/basic.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/workflows/basic.yml b/workflows/basic.yml index 6840746..0287725 100644 --- a/workflows/basic.yml +++ b/workflows/basic.yml @@ -28,7 +28,7 @@ jobs: - name: Run coverage run: | - pytest --cov-config=.coveragerc --cov=./pkmodel --cov-report=xml --cov-branch + pytest --cov-config=.coveragerc --cov=./src/pkmodel --cov-report=xml --cov-branch cat coverage.xml - name: Upload coverage reports to Codecov From f5ca04549b4275ca87842f33981471108eda88d9 Mon Sep 17 00:00:00 2001 From: Sixtine Dromigny Date: Thu, 19 Oct 2023 13:42:01 +0100 Subject: [PATCH 24/27] issue #7 and #15 are resolved:parametrising and integration functions are inside Class Model with 2 children IV and SC, depending on which model the user wants to use --- pkmodel/model.py | 111 ++++++++++++++++++++++++++++++----------------- 1 file changed, 70 insertions(+), 41 deletions(-) diff --git a/pkmodel/model.py b/pkmodel/model.py index de51173..3ca524a 100644 --- a/pkmodel/model.py +++ b/pkmodel/model.py @@ -25,39 +25,53 @@ def __init__(self, parameters=[0, 0, 0, 0, 0]): super().__init__() self.parameters = parameters - def param(self, y, t): + def paramIV(self, y, t): Q_p1, V_c, V_p1, CL, X = self.parameters q_c, q_p1 = y transition = Q_p1 * (q_c / V_c - q_p1 / V_p1) dqc_dt = X - q_c / V_c * CL - transition dqp1_dt = transition return [dqc_dt, dqp1_dt] + + def integrate(): + iv_instance = IV() + t_eval = np.linspace(0, 1, 1000) + y0 = [0.0, 0.0] + iv_instance.parameters = parameters + solution = odeint(iv_instance.paramIV, y0, t_eval) + q_c, q_p1 = solution.T + return np.array([q_c,q_p1]) +############TESTING IF CLASS WORKS +# parameters = [0.7, 1, 2, 3, 4] +# test1=IV.integrate() +# print('test1',test1.shape) -# Create an instance of the IV class -iv_instance = IV() +############INTEGRATION OUTSIDE THE CLASS +# # Create an instance of the IV class +# iv_instance = IV() -# Define the time points at which you want to evaluate the solution -t_eval = np.linspace(0, 1, 1000) +# # Define the time points at which you want to evaluate the solution +# t_eval = np.linspace(0, 1, 1000) -# Initial conditions -y0 = [0.0, 0.0] +# # Initial conditions +# y0 = [0.0, 0.0] -# Parameters -parameters = [0.7, 1, 2, 3, 4] +# # Parameters +# parameters = [0.7, 1, 2, 3, 4] -# Set the parameters in the instance -iv_instance.parameters = parameters +# # Set the parameters in the instance +# iv_instance.parameters = parameters -# Solve the ODEs using odeint -solution = odeint(iv_instance.param, y0, t_eval) +# # Solve the ODEs using odeint +# solution = odeint(iv_instance.paramIV, y0, t_eval) -# Extract the results -q_c, q_p1 = solution.T +# # Extract the results +# q_c, q_p1 = solution.T # Print the results -print(q_c) -print(q_p1) +# print(q_c) +# print(q_p1) class SC(Model): @@ -66,41 +80,56 @@ def __init__(self, parameters=[0, 0, 0, 0, 0,0]): super().__init__() self.parameters = parameters - def param(self, y, t): + def paramSC(self, y, t): Q_p1, V_c, V_p1, CL, X, ka = self.parameters - q_c, q_p1, q0= y - dq0_dt = X - ka*q0 + q_c, q_p1, q_0= y + dq0_dt = X - ka*q_0 transition = Q_p1 * (q_c / V_c - q_p1 / V_p1) - dqc_dt = ka*q0 - q_c / V_c * CL - transition + dqc_dt = ka*q_0 - q_c / V_c * CL - transition dqp1_dt = transition return [dqc_dt, dqp1_dt,dq0_dt] + def integrate(): + sc_instance = SC() + t_eval = np.linspace(0, 1, 1000) + y0 = [0.0, 0.0, 0.0] + sc_instance.parameters = parameters + solution = odeint(sc_instance.paramSC, y0, t_eval) + q_c, q_p1, q_0 = solution.T + return np.array([q_c,q_p1,q_0]) -# Create an instance of the IV class -sc_instance = SC() -# Define the time points at which you want to evaluate the solution -t_eval = np.linspace(0, 1, 1000) +############TESTING IF CLASS WORKS +# parameters = [0.7, 1, 2, 3, 4, 5] +# test2=SC.integrate() +# print('test2',test2.shape) -# Initial conditions -y0 = [0.0, 0.0,0] +############INTEGRATION OUTSIDE THE CLASS +# # Create an instance of the IV class +# sc_instance = SC() -# Parameters -parameters = [0.7, 1, 2, 3, 4,7] +# # Define the time points at which you want to evaluate the solution +# t_eval = np.linspace(0, 1, 1000) -# Set the parameters in the instance -sc_instance.parameters = parameters +# # Initial conditions +# y0 = [0.0, 0.0,0] -# Solve the ODEs using odeint -solution = odeint(sc_instance.param, y0, t_eval) +# # Parameters +# parameters = [0.7, 1, 2, 3, 4,7] -print(solution.shape) +# # Set the parameters in the instance +# sc_instance.parameters = parameters -# Extract the results -print(solution.T.shape) -q_c, q_p1, q_0 = solution.T +# # Solve the ODEs using odeint +# solution = odeint(sc_instance.paramSC, y0, t_eval) -# Print the results -print(q_c.shape) -print(q_p1.shape) -print(solution.y[0, :]) +# print(solution.shape) + +# # Extract the results +# # print(solution.T.shape) +# q_c, q_p1, q_0 = solution.T + +# # Print the results +# # print(q_c.shape) +# # print(q_p1.shape) +# # print(solution.y[0, :]) From 58529d670d7f95c82c29031a81f1286ab6239dd3 Mon Sep 17 00:00:00 2001 From: Sixtine Dromigny Date: Thu, 19 Oct 2023 14:00:18 +0100 Subject: [PATCH 25/27] try to make the dev and the sixtine-functions braches merge --- pkmodel/solution.py | 40 ---------------------------------------- 1 file changed, 40 deletions(-) diff --git a/pkmodel/solution.py b/pkmodel/solution.py index 7dbd29e..8a41bd8 100644 --- a/pkmodel/solution.py +++ b/pkmodel/solution.py @@ -14,43 +14,3 @@ class Solution: """ def __init__(self, value=44): self.value = value - def plot(): - t_eval = np.linspace(0, 1, 1000) - y0 = np.array([0.0, 0.0]) - - fig = plt.figure() - - args = [ - model1_args['Q_p1'], model1_args['V_c'], model1_args['V_p1'], model1_args['CL'], model1_args['X'] - ] - sol = scipy.integrate.solve_ivp( - fun=lambda t, y: IV(t, y, *args), - t_span=[t_eval[0], t_eval[-1]], - y0=y0, t_eval=t_eval - ) - plt.plot(sol.t, sol.y[0, :], label=model1_args['name'] + '- q_c') - plt.plot(sol.t, sol.y[1, :], label=model1_args['name'] + '- q_p1') - - - - y0 = np.array([0.0, 0.0, 0.0]) - - args = [ - model2_args['Q_p1'], model2_args['V_c'], model2_args['V_p1'], model2_args['CL'], model2_args['X'], model2_args['ka'] - ] - sol = scipy.integrate.solve_ivp( - fun=lambda t, y: SC(t, y, *args), - t_span=[t_eval[0], t_eval[-1]], - y0=y0, t_eval=t_eval - ) - plt.plot(sol.t, sol.y[0, :], label=model2_args['name'] + '- q_c') - plt.plot(sol.t, sol.y[1, :], label=model2_args['name'] + '- q_p1') - - plt.legend() - plt.ylabel('drug mass [ng]') - plt.xlabel('time [h]') - - plt.savefig('plot.png') - -## package importing - From 8589c602fee6d46bce1efd70ac29462a07ffaa63 Mon Sep 17 00:00:00 2001 From: Sixtine Dromigny Date: Thu, 19 Oct 2023 15:34:44 +0100 Subject: [PATCH 26/27] Rhiannon-s code added in solution.py in srd/pkmodel --- src/pkmodel/solution.py | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/src/pkmodel/solution.py b/src/pkmodel/solution.py index 8a41bd8..5c46a6f 100644 --- a/src/pkmodel/solution.py +++ b/src/pkmodel/solution.py @@ -1,16 +1,27 @@ -# -# Solution class -# +import numpy as np +import matplotlib.pylab as plt +import model -class Solution: - """A Pharmokinetic (PK) model solution +def visualise(modeldata): + time=np.linspace(0,1,1000) + fig, ax = plt.subplots() + # Plot q_c + plt.plot(time, modeldata[0,:], label = 'q_c') + # Plot q_p1 + plt.plot(time, modeldata[1,:], label = 'q_p1') + # Plot q_0 + if np.shape(modeldata) == (3, 1000): + plt.plot(time, modeldata[2,:], label = 'q_0') + plt.title('Subcutaneous model') + else: + plt.title('IV model') + plt.legend() + ax.set_ylabel('drug mass (ng)') + ax.set_xlabel('time [h]') + #plt.savefig('plot.png') + plt.show() - Parameters - ---------- +parameter=[1,2,3,4,5] - value: numeric, optional - an example paramter - - """ - def __init__(self, value=44): - self.value = value +result=visualise(model.IV.integrate()) +print(result) \ No newline at end of file From 02fd8f902e7f0096b3aae3d59654d78bdfa96e9b Mon Sep 17 00:00:00 2001 From: Sixtine Dromigny Date: Thu, 19 Oct 2023 15:56:34 +0100 Subject: [PATCH 27/27] solution.py works! --- pkmodel/model.py | 135 ++++++++++++++++++++++++++++++++++++++++ pkmodel/solution.py | 91 ++++++--------------------- src/pkmodel/model.py | 32 +++++----- src/pkmodel/solution.py | 11 ++-- 4 files changed, 176 insertions(+), 93 deletions(-) create mode 100644 pkmodel/model.py diff --git a/pkmodel/model.py b/pkmodel/model.py new file mode 100644 index 0000000..57f0b3b --- /dev/null +++ b/pkmodel/model.py @@ -0,0 +1,135 @@ +# +# Model class +# +import matplotlib.pylab as plt +import numpy as np +import scipy.integrate +from scipy.integrate import odeint + +class Model: + """A Pharmokinetic (PK) model + + Parameters + ---------- + + value: numeric, optional + an example paramter + + """ + def __init__(self, value=42): + self.value = value + +class IV(Model): + # Your class definition here + def __init__(self, parameters=[0, 0, 0, 0, 0]): + super().__init__() + self.parameters = parameters + + def paramIV(self, y, t): + Q_p1, V_c, V_p1, CL, X = self.parameters + q_c, q_p1 = y + transition = Q_p1 * (q_c / V_c - q_p1 / V_p1) + dqc_dt = X - q_c / V_c * CL - transition + dqp1_dt = transition + return [dqc_dt, dqp1_dt] + + def integrate(): + iv_instance = IV() + t_eval = np.linspace(0, 1, 1000) + y0 = [0.0, 0.0] + iv_instance.parameters = parameters + solution = odeint(iv_instance.paramIV, y0, t_eval) + q_c, q_p1 = solution.T + return np.array([q_c,q_p1]) + +############TESTING IF CLASS WORKS +# parameters = [0.7, 1, 2, 3, 4] +# test1=IV.integrate() +# print('test1',test1.shape) + +############INTEGRATION OUTSIDE THE CLASS +# # Create an instance of the IV class +# iv_instance = IV() + +# # Define the time points at which you want to evaluate the solution +# t_eval = np.linspace(0, 1, 1000) + +# # Initial conditions +# y0 = [0.0, 0.0] + +# # Parameters +# parameters = [0.7, 1, 2, 3, 4] + +# # Set the parameters in the instance +# iv_instance.parameters = parameters + +# # Solve the ODEs using odeint +# solution = odeint(iv_instance.paramIV, y0, t_eval) + +# # Extract the results +# q_c, q_p1 = solution.T + +# Print the results +# print(q_c) +# print(q_p1) + + +class SC(Model): + "subcutaneous model" + def __init__(self, parameters=[0, 0, 0, 0, 0,0]): + super().__init__() + self.parameters = parameters + + def paramSC(self, y, t): + Q_p1, V_c, V_p1, CL, X, ka = self.parameters + q_c, q_p1, q_0= y + dq0_dt = X - ka*q_0 + transition = Q_p1 * (q_c / V_c - q_p1 / V_p1) + dqc_dt = ka*q_0 - q_c / V_c * CL - transition + dqp1_dt = transition + return [dqc_dt, dqp1_dt,dq0_dt] + + def integrate(): + sc_instance = SC() + t_eval = np.linspace(0, 1, 1000) + y0 = [0.0, 0.0, 0.0] + sc_instance.parameters = parameters + solution = odeint(sc_instance.paramSC, y0, t_eval) + q_c, q_p1, q_0 = solution.T + return np.array([q_c,q_p1,q_0]) + + +############TESTING IF CLASS WORKS +# parameters = [0.7, 1, 2, 3, 4, 5] +# test2=SC.integrate() +# print('test2',test2.shape) + +############INTEGRATION OUTSIDE THE CLASS +# # Create an instance of the IV class +# sc_instance = SC() + +# # Define the time points at which you want to evaluate the solution +# t_eval = np.linspace(0, 1, 1000) + +# # Initial conditions +# y0 = [0.0, 0.0,0] + +# # Parameters +# parameters = [0.7, 1, 2, 3, 4,7] + +# # Set the parameters in the instance +# sc_instance.parameters = parameters + +# # Solve the ODEs using odeint +# solution = odeint(sc_instance.paramSC, y0, t_eval) + +# print(solution.shape) + +# # Extract the results +# # print(solution.T.shape) +# q_c, q_p1, q_0 = solution.T + +# # Print the results +# # print(q_c.shape) +# # print(q_p1.shape) +# # print(solution.y[0, :]) \ No newline at end of file diff --git a/pkmodel/solution.py b/pkmodel/solution.py index 3f2cad7..5c46a6f 100644 --- a/pkmodel/solution.py +++ b/pkmodel/solution.py @@ -1,80 +1,27 @@ -# -# Solution class -# - -class Solution: - """A Pharmokinetic (PK) model solution - - Parameters - ---------- - - value: numeric, optional - an example paramter - - """ - def __init__(self, value=44): - self.value = value - def plot(): - t_eval = np.linspace(0, 1, 1000) - y0 = np.array([0.0, 0.0]) - - fig = plt.figure() - - args = [ - model1_args['Q_p1'], model1_args['V_c'], model1_args['V_p1'], model1_args['CL'], model1_args['X'] - ] - sol = scipy.integrate.solve_ivp( - fun=lambda t, y: IV(t, y, *args), - t_span=[t_eval[0], t_eval[-1]], - y0=y0, t_eval=t_eval - ) - plt.plot(sol.t, sol.y[0, :], label=model1_args['name'] + '- q_c') - plt.plot(sol.t, sol.y[1, :], label=model1_args['name'] + '- q_p1') - - - - y0 = np.array([0.0, 0.0, 0.0]) - - args = [ - model2_args['Q_p1'], model2_args['V_c'], model2_args['V_p1'], model2_args['CL'], model2_args['X'], model2_args['ka'] - ] - sol = scipy.integrate.solve_ivp( - fun=lambda t, y: SC(t, y, *args), - t_span=[t_eval[0], t_eval[-1]], - y0=y0, t_eval=t_eval - ) - plt.plot(sol.t, sol.y[0, :], label=model2_args['name'] + '- q_c') - plt.plot(sol.t, sol.y[1, :], label=model2_args['name'] + '- q_p1') - - plt.legend() - plt.ylabel('drug mass [ng]') - plt.xlabel('time [h]') - - plt.savefig('plot.png') - - import numpy as np -import matplotlib.pyplot as plt -t_eval = np.linspace(0,10,100) -q_c = t_eval +20 -q_p1 = t_eval +3 +import matplotlib.pylab as plt +import model -def visualise(t_eval, q_c, q_p1): +def visualise(modeldata): + time=np.linspace(0,1,1000) fig, ax = plt.subplots() - #plt.plot(t_eval, q_c, label=Model.name + '- q_c') - #plt.plot(t_eval, q_p1, label=Model.name + '- q_p1') - ax.plot(t_eval, q_c) - ax.plot(t_eval, q_p1) - #plt.legend() + # Plot q_c + plt.plot(time, modeldata[0,:], label = 'q_c') + # Plot q_p1 + plt.plot(time, modeldata[1,:], label = 'q_p1') + # Plot q_0 + if np.shape(modeldata) == (3, 1000): + plt.plot(time, modeldata[2,:], label = 'q_0') + plt.title('Subcutaneous model') + else: + plt.title('IV model') + plt.legend() ax.set_ylabel('drug mass (ng)') ax.set_xlabel('time [h]') - + #plt.savefig('plot.png') plt.show() - return fig - -visualise(t_eval, q_c, q_p1) - - -## package importing +parameter=[1,2,3,4,5] +result=visualise(model.IV.integrate()) +print(result) \ No newline at end of file diff --git a/src/pkmodel/model.py b/src/pkmodel/model.py index 3ca524a..6096cdf 100644 --- a/src/pkmodel/model.py +++ b/src/pkmodel/model.py @@ -33,19 +33,19 @@ def paramIV(self, y, t): dqp1_dt = transition return [dqc_dt, dqp1_dt] - def integrate(): - iv_instance = IV() + def integrate(self): t_eval = np.linspace(0, 1, 1000) y0 = [0.0, 0.0] - iv_instance.parameters = parameters - solution = odeint(iv_instance.paramIV, y0, t_eval) + solution = odeint(self.paramIV, y0, t_eval) q_c, q_p1 = solution.T return np.array([q_c,q_p1]) -############TESTING IF CLASS WORKS -# parameters = [0.7, 1, 2, 3, 4] -# test1=IV.integrate() -# print('test1',test1.shape) +###########TESTING IF CLASS WORKS +parameters = [0.7, 1, 2, 3, 4] +test0 = IV(parameters=parameters) +test1 = test0.integrate() +#test1=IV.integrate() +print('test1',test1.shape) ############INTEGRATION OUTSIDE THE CLASS # # Create an instance of the IV class @@ -89,20 +89,22 @@ def paramSC(self, y, t): dqp1_dt = transition return [dqc_dt, dqp1_dt,dq0_dt] - def integrate(): - sc_instance = SC() + def integrate(self): + t_eval = np.linspace(0, 1, 1000) y0 = [0.0, 0.0, 0.0] - sc_instance.parameters = parameters - solution = odeint(sc_instance.paramSC, y0, t_eval) + + solution = odeint(self.paramSC, y0, t_eval) q_c, q_p1, q_0 = solution.T return np.array([q_c,q_p1,q_0]) ############TESTING IF CLASS WORKS -# parameters = [0.7, 1, 2, 3, 4, 5] -# test2=SC.integrate() -# print('test2',test2.shape) +parameters = [0.7, 1, 2, 3, 4,6] +test0 = SC(parameters=parameters) +test1 = test0.integrate() +#test1=IV.integrate() +print('test1',test1.shape) ############INTEGRATION OUTSIDE THE CLASS # # Create an instance of the IV class diff --git a/src/pkmodel/solution.py b/src/pkmodel/solution.py index 5c46a6f..1f7b99c 100644 --- a/src/pkmodel/solution.py +++ b/src/pkmodel/solution.py @@ -18,10 +18,9 @@ def visualise(modeldata): plt.legend() ax.set_ylabel('drug mass (ng)') ax.set_xlabel('time [h]') - #plt.savefig('plot.png') - plt.show() + plt.savefig('plot_vis.png') + #plt.show() -parameter=[1,2,3,4,5] - -result=visualise(model.IV.integrate()) -print(result) \ No newline at end of file +parameters=[1,2,3,4,5,6] +test0 = model.SC(parameters=parameters) +result=visualise(model.SC.integrate(test0))