### Install required packages Source: https://isbgroup.eu/sund-toolbox/2.4.1/examples/usecases/parameter-estimation.html Commands to install the necessary dependencies for running the parameter estimation example. ```bash uv add sund numpy cma scipy ``` ```bash pip install sund numpy cma scipy ``` -------------------------------- ### Install Required Packages Source: https://isbgroup.eu/sund-toolbox/2.4.1/examples/usecases/parameter-estimation.html Commands to install the necessary dependencies for running the parameter estimation example. ```bash uv add sund numpy pypesto ``` ```bash pip install sund numpy pypesto ``` -------------------------------- ### Install SUND and dependencies Source: https://isbgroup.eu/sund-toolbox/2.4.1/examples/usecases/parameter-estimation.html Commands to install the required packages for running the parameter estimation example. ```bash uv add sund numpy scipy ``` ```bash pip install sund numpy scipy ``` -------------------------------- ### Install SUND from PyPI Source: https://isbgroup.eu/sund-toolbox/2.4.1/index.html Standard installation commands using uv or pip. ```bash uv add sund ``` ```bash pip install sund ``` -------------------------------- ### Install SUND from URL Source: https://isbgroup.eu/sund-toolbox/2.4.1/index.html Installation commands for specific versions or the latest release hosted on the project homepage. ```bash uv add https://isbgroup.eu/sund-toolbox/releases/sund-latest.tar.gz # Latest version uv add https://isbgroup.eu/sund-toolbox/releases/sund-.tar.gz # Specific version ``` ```bash pip install https://isbgroup.eu/sund-toolbox/releases/sund-latest.tar.gz # Latest version pip install https://isbgroup.eu/sund-toolbox/releases/sund-.tar.gz # Specific version ``` -------------------------------- ### Compiler Benchmark Example Source: https://isbgroup.eu/sund-toolbox/2.4.1/examples/compiler-benchmark.ipynb A basic example demonstrating compiler benchmarking. ```text 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 ``` -------------------------------- ### Install required packages Source: https://isbgroup.eu/sund-toolbox/2.4.1/examples/models/minimal-ode-model.html Install the necessary dependencies using either uv or pip. ```bash uv add sund numpy matplotlib ``` ```bash pip install sund numpy matplotlib ``` -------------------------------- ### Install latest version from URL Source: https://isbgroup.eu/sund-toolbox/2.4.1/versions.html Use these commands to install the latest version of the toolbox directly from the project's release URL. ```shell uv add https://isbgroup.eu/sund-toolbox/releases/sund-latest.tar.gz ``` ```shell pip install https://isbgroup.eu/sund-toolbox/releases/sund-latest.tar.gz ``` -------------------------------- ### Full parameter estimation workflow Source: https://isbgroup.eu/sund-toolbox/2.4.1/examples/usecases/parameter-estimation.html A complete Python script demonstrating data loading, model installation, simulation setup, objective function definition, and optimization using differential evolution. ```python # %% Import packages import json from pathlib import Path import numpy as np from scipy.optimize import Bounds, differential_evolution import sund # Create a numpy serializer for json class NumpyEncoder(json.JSONEncoder): def default(self, o): if isinstance(o, np.ndarray): return o.tolist() return super().default(o) # %% Load the data and get the total time vector for all observables in the experiments data = json.loads(Path("data_m1.json").read_text()) for experiment in data: all_times = [ t for observable in data[experiment]["observables"] for t in data[experiment]["observables"][observable]["time"] ] # Store the time vector for each experiment data[experiment]["all_times"] = sorted(np.unique(all_times)) # %% Install and load the model sund.install_model("m1.txt") m1 = sund.load_model("m1") # %% Create a activity objects activity1 = sund.Activity(time_unit="m") activity1.add_output( type="piecewise_constant", name="activation", t=data["dose1"]["inputs"]["activation"]["t"], f=data["dose1"]["inputs"]["activation"]["f"], ) activity2 = sund.Activity(time_unit="m") activity2.add_output( type="piecewise_constant", name="activation", t=data["dose2"]["inputs"]["activation"]["t"], f=data["dose2"]["inputs"]["activation"]["f"], ) # %% Create simulation objects m1_sims = {} m1_sims["dose1"] = sund.Simulation( models=m1, activities=activity1, time_unit="m", time_vector=data["dose1"]["all_times"], ) m1_sims["dose2"] = sund.Simulation( models=m1, activities=activity2, time_unit="m", time_vector=data["dose2"]["all_times"], ) # %% Define a objective function def obj_fun(params, sims, data): cost = 0 for experiment in data: try: sims[experiment].simulate(parameter_values=params) for observable_key, observable_data in data[experiment]["observables"].items(): feature_idx = sims[experiment].feature_names.index(observable_key) t_idx = np.where(np.isin(sims[experiment].time_vector, observable_data["time"])) y_sim = sims[experiment].feature_values[t_idx, feature_idx] y = observable_data["mean"] sem = observable_data["SEM"] cost += np.sum(np.square((y_sim - y) / sem)) except Exception as e: if "CVODE" not in str(e): print(f"Error in {experiment}: {e}") raise cost += 1e29 # in-case of CVODE error exception add a "high cost" return cost # Define a function to use parameters in log-space to calculate the cost def obj_fun_log(params_log, sim, data): params = np.exp(params_log.copy()) return obj_fun(params, sim, data) # %% Prepare input for the optimization # Define a initial parameter set params0_m1 = [1, 0.0001, 1000000] # = [k1, k2, kfeed] x0_log_m1 = np.log(params0_m1) # parameter bounds bounds_m1_log = Bounds( [np.log(1e-6)] * len(x0_log_m1), [np.log(1e6)] * len(x0_log_m1), ) # Create a bounds object # callback function to save the current parameter values and cost def callback_m1(x, _convergence): out = {"x": list(x)} Path("m1-temp.json").write_text(json.dumps(out)) def callback_m1_log(x, convergence): callback_m1(np.exp(x.copy()), convergence) # arguments for the objective function args_m1 = (m1_sims, data) # %% call the optimization function res = differential_evolution( func=obj_fun_log, bounds=bounds_m1_log, args=args_m1, x0=x0_log_m1, callback=callback_m1_log, disp=True, ) # This is the optimization # %% Print and extract the results res["x"] = np.exp(res["x"]) # convert back from log scale print(f"\nOptimized parameter values: {res['x']}") print(f"Optimized cost: {res['fun']}") # save the results to a json file file_name = f"m1 ({res['fun']:.3f}).json" res_out = {"f": res["fun"], "x": res["x"]} Path(file_name).write_text(json.dumps(res_out, cls=NumpyEncoder)) ``` -------------------------------- ### Install and Load Models Source: https://isbgroup.eu/sund-toolbox/2.4.1/examples/published/herrgardh_2023/herrgardh_2023.ipynb Demonstrates how to install and load various physiological models into the sund environment. ```python # %% Import the model sund.install_model(herrgardh_2023_str) Herrgardh_2023 = sund.load_model("Herrgardh_2023") # %% Import the segmented model parts sund.install_model(brannmark_2013_str) Brannmark = sund.load_model("Brannmark_2013") sund.install_model(dallaman2007_str) DallaMan = sund.load_model("DallaMan_2007") sund.install_model(hall_2011_str) Hall = sund.load_model("Hall_2011") sund.install_model(herrgardh_2021_str) Herrgardh_2021 = sund.load_model("Herrgardh_2021") sund.install_model(herrgardh_2023_top_str) ``` -------------------------------- ### Install a model Source: https://isbgroup.eu/sund-toolbox/2.4.1/functionality/install-import-load.html Use install_model to register a model file for use. ```python sund.install_model('model.txt') ``` -------------------------------- ### Install required packages Source: https://isbgroup.eu/sund-toolbox/2.4.1/examples/usecases/training-validation-and-uncertainty.html Commands to install the necessary dependencies for the project. ```bash uv add sund numpy scipy matplotlib ``` ```bash pip install sund numpy scipy matplotlib ``` -------------------------------- ### Import Model Source: https://isbgroup.eu/sund-toolbox/2.4.1/model-format/model-format.html Load a defined model after installation. ```python sund.import_model('my_model') ``` -------------------------------- ### SimulationObject.simulate usage example Source: https://isbgroup.eu/sund-toolbox/2.4.1/modules/simulation/simulate.html Demonstrates the required keyword-only argument syntax for calling the simulate method. ```python sim.simulate(time_vector=..., parameter_values=..., reset=True) ``` -------------------------------- ### Retrieve installed models list Source: https://isbgroup.eu/sund-toolbox/2.4.1/modules/public_functions/installed_models.html Returns a list of strings representing the names of all models currently installed in the package. ```python def installed_models() -> list[str]: """Produces a list of the names of the installed models. Returns: A list of installed models """ pkgpath = Path(__file__).parent / "Models" return [name for _, name, _ in pkgutil.iter_modules([str(pkgpath)])] ``` -------------------------------- ### Benchmark Model Compilation with Different Compilers Source: https://isbgroup.eu/sund-toolbox/2.4.1/examples/compiler-benchmark.ipynb Demonstrates how to switch between Zig and system compilers to install performance models, including error handling for missing compiler availability. ```python from sund.tools import SundCompilerError zig_name = "bench_compiler_zig" sys_name = "bench_compiler_system" for name in [zig_name, sys_name]: if name in sund.installed_models(): sund.uninstall_model(name) # Install with zig print("Compiling model with zig...") sund.set_compiler("zig") try: sund.install_model(_make_perf_model(zig_name)) print(f" Done. Installed '{zig_name}' with zig compiler.") except SundCompilerError as e: print(f" zig compiler not available — cannot run benchmark.\n {e}") raise SystemExit from e # Install with system compiler print("Compiling model with system compiler...") sund.set_compiler("system") try: sund.install_model(_make_perf_model(sys_name)) print(f" Done. Installed '{sys_name}' with system compiler.") except SundCompilerError as e: print(f" System compiler not available — cannot run benchmark.\n {e}") ``` -------------------------------- ### sund.install_model Source: https://isbgroup.eu/sund-toolbox/2.4.1/functionality/install-import-load.html Installs a model from a file path. Supports specifying the compiler optimization level. ```APIDOC ## sund.install_model(path, compile_optimization_level) ### Description Installs a model from the specified file path so it can be loaded or imported later. ### Parameters - **path** (string) - Required - The file path to the model definition (e.g., 'model.txt'). - **compile_optimization_level** (int) - Optional - Optimization level for compilation (0, 1, 2, or 3). Defaults to 2. ``` -------------------------------- ### Initial State Conditions Source: https://isbgroup.eu/sund-toolbox/2.4.1/examples/published/herrgardh_2023/herrgardh_2023.ipynb Starting values for the model variables at time zero. ```text betamass(0) = 1 diabetes(0) = 0 G_p(0) = 159.2072 G_t(0) = 130 I_l(0) = 4.5 I_p(0) = 1.4950 Q_sto1(0) = 0 Q_sto2(0) = 0 Q_gut(0) = 0 I_1(0) = 25 I_d(0) = 25 I_po(0) = 3.6 Y(0) = 0 Y2(0) = 0 INS_f(0) = 0 INS(0) = 0 RE(0) = 0 Glu_in(0) = 2.470962100570481 G6P(0) = 0.004273753196181 ``` -------------------------------- ### Load a model object Source: https://isbgroup.eu/sund-toolbox/2.4.1/functionality/install-import-load.html Create a model object from an installed model using load_model. ```python model = sund.load_model('model') ``` -------------------------------- ### Implementation of sund.install_model Source: https://isbgroup.eu/sund-toolbox/2.4.1/modules/public_functions/install_model.html This function checks for existing installations, manages module unloading, handles file system cleanup, and performs model compilation. ```python # Check if already installed and up to date if not force and model["NAME"] in installed_models() and modulefile.exists(): existing_hash = _read_model_hash(hashfile) if hashfile.exists() else None if existing_hash == current_hash: logger.info("Model '%s' is already installed and up to date.", model["NAME"]) continue if existing_hash is None: logger.info( "Model '%s' is missing content hash. Reinstalling model and creating hash sidecar.", # noqa: E501 model["NAME"], ) else: logger.info( "Model '%s' content differs from installed version. Reinstalling.", model["NAME"], ) # Check if imported if ("sund.Models." + model["NAME"]) in sys.modules: logger.warning( "Model '%s' has already been imported into memory. Trying to unload the module, but you might need to restart Python before re-installing the model.", # noqa: E501 model["NAME"], ) sys.modules.pop("sund.Models." + model["NAME"]) # Check if modulefile exist on file system and remove if modulefile.exists(): try: modulefile.unlink() except (OSError, PermissionError) as err: msg = f"Model '{model['NAME']}' cannot be re-installed, probably because it is being used by another process. Try terminating any process that might use the model and try again." # noqa: E501 raise ValueError(msg) from err if hashfile.exists(): with contextlib.suppress(builtins.BaseException): hashfile.unlink() # create C-file and module file logger.info("Compiling model '%s'...", model["NAME"]) cfile = tools._model_cfile(model) tools._model_module_file(cfile, compile_optimization_level=compile_optimization_level) if not save_compiled_model: Path(cfile).unlink() logger.info("Model '%s' successfully installed.", model["NAME"]) try: _write_model_hash(hashfile, current_hash) except Exception as e: # noqa: BLE001 warnings.warn( f"Could not write hash file for model '{model['NAME']}': {e}", stacklevel=2, ) ``` -------------------------------- ### Execute ODE model simulation Source: https://isbgroup.eu/sund-toolbox/2.4.1/examples/models/minimal-ode-model.html Full workflow for installing, loading, configuring, and simulating a model with SUND. ```python # %% Import packages import matplotlib.pyplot as plt import numpy as np import sund # %% Define the model name model_name = "minimal_ode" # %% Install the model by using the SUND function 'install_model' sund.install_model(f"{model_name}.txt") # %% Import the model object by using the SUND function 'load_model' model = sund.load_model(f"{model_name}") # %% The built in model objects functions can now be used model.state_values = [2, 2] print(model.state_values) model.reset_states() print(model.state_values) # %% A simulation object can be constructed from the model template sim1 = sund.Simulation(models=model, time_unit=model.time_unit) print(sim1.state_values) # Note that the simulation object will be crated from the current instance of the model object model.state_values = [2, 2] sim2 = sund.Simulation(models=model, time_unit=model.time_unit) print(sim2.state_values) # %% Now we can simulate the model using the simulation object sim1.simulate(time_vector=np.linspace(0, 10, 100)) fig = plt.figure() feature_index = sim1.feature_names.index("yA") plt.plot(sim1.time_vector, sim1.feature_values[:, feature_index]) plt.xlabel(sim1.time_unit) plt.ylabel("A.U.") plt.title("Simulation result") # %% Simulating the object again will start the simulation from the last result sim1.simulate(time_vector=np.linspace(0, 10, 100)) fig = plt.figure() feature_index = sim1.feature_names.index("yA") plt.plot(sim1.time_vector, sim1.feature_values[:, feature_index]) plt.xlabel(sim1.time_unit) plt.ylabel("A.U.") plt.title("Simulation result") # %% to recreate the original results we need to reset the simulation object sim1.reset_states() sim1.simulate(time_vector=np.linspace(0, 10, 100)) fig = plt.figure() feature_index = sim1.feature_names.index("yA") plt.plot(sim1.time_vector, sim1.feature_values[:, feature_index]) plt.xlabel(sim1.time_unit) plt.ylabel("A.U.") plt.title("Simulation result") plt.show() ``` -------------------------------- ### Full parameter estimation workflow Source: https://isbgroup.eu/sund-toolbox/2.4.1/examples/usecases/parameter-estimation.html A comprehensive script covering data preparation, model setup, objective function definition, and optimization using CMA-ES and Nelder-Mead. ```python # %% Import packages import json from pathlib import Path import cma import numpy as np from scipy.optimize import minimize as scipy_minimize import sund # Create a numpy serializer for json class NumpyEncoder(json.JSONEncoder): def default(self, o): if isinstance(o, np.ndarray): return o.tolist() return super().default(o) # %% Load the data and get the total time vector for all observables in the experiments data = json.loads(Path("data_m1.json").read_text()) for experiment in data: all_times = [ t for observable in data[experiment]["observables"] for t in data[experiment]["observables"][observable]["time"] ] data[experiment]["all_times"] = sorted(np.unique(all_times)) # %% Install and load the model sund.install_model("m1.txt") m1 = sund.load_model("m1") # %% Create activity objects activity1 = sund.Activity(time_unit="m") activity1.add_output( type="piecewise_constant", name="activation", t=data["dose1"]["inputs"]["activation"]["t"], f=data["dose1"]["inputs"]["activation"]["f"], ) activity2 = sund.Activity(time_unit="m") activity2.add_output( type="piecewise_constant", name="activation", t=data["dose2"]["inputs"]["activation"]["t"], f=data["dose2"]["inputs"]["activation"]["f"], ) # %% Create simulation objects m1_sims = {} m1_sims["dose1"] = sund.Simulation( models=m1, activities=activity1, time_unit="m", time_vector=data["dose1"]["all_times"], ) m1_sims["dose2"] = sund.Simulation( models=m1, activities=activity2, time_unit="m", time_vector=data["dose2"]["all_times"], ) # %% Define an objective function def obj_fun(params, sims, data): cost = 0 for experiment in data: try: sims[experiment].simulate(parameter_values=params) for observable_key, observable_data in data[experiment]["observables"].items(): feature_idx = sims[experiment].feature_names.index(observable_key) t_idx = np.where(np.isin(sims[experiment].time_vector, observable_data["time"])) y_sim = sims[experiment].feature_values[t_idx, feature_idx] y = observable_data["mean"] sem = observable_data["SEM"] cost += np.sum(np.square((y_sim - y) / sem)) except Exception as e: if "CVODE" not in str(e): print(f"Error in {experiment}: {e}") raise cost += 1e29 return cost def obj_fun_log(params_log, sims, data): params = np.exp(params_log) return obj_fun(params, sims, data) # %% Prepare input for the optimization params0 = [1, 0.0001, 1000000] # = [k1, k2, kfeed] x0_log = np.log(params0) # Parameter bounds (log-space) lb = [np.log(1e-6)] * len(x0_log) ub = [np.log(1e6)] * len(x0_log) # %% Run CMA-ES optimization # Scale population size and iterations with number of parameters n_params = len(x0_log) popsize = max(50, int(10 * np.sqrt(n_params))) maxiter = max(100, (1000 * n_params) // popsize) cma_options = { "bounds": [lb, ub], "maxiter": maxiter, "popsize": popsize, "verbose": 1, "tolfun": 1e-9, "tolx": 1e-9, } # Wrap the objective so CMA-ES only passes the parameter vector def objective(x): return obj_fun_log(x, m1_sims, data) # Callback to save progress def cma_callback(es): out = {"x": np.exp(es.result.xbest).tolist(), "f": es.result.fbest} Path("m1-temp.json").write_text(json.dumps(out)) sigma0 = 0.3 # initial step size res = cma.CMAEvolutionStrategy(x0_log, sigma0, inopts=cma_options).optimize( objective, callback=cma_callback ).result # %% Local polish with Nelder-Mead # CMA-ES is good at finding the right region, but a local solver can # refine the solution further. polish_res = scipy_minimize( objective, x0=res.xbest, method="Nelder-Mead", bounds=list(zip(lb, ub)), options={"maxfev": max(200, 200 * n_params), "xatol": 1e-9, "fatol": 1e-9, "adaptive": True}, ) if polish_res.fun < res.fbest: print(f"Nelder-Mead improved: {res.fbest:.6g} -> {polish_res.fun:.6g}") best_params = np.exp(polish_res.x) best_cost = polish_res.fun else: best_params = np.exp(res.xbest) best_cost = res.fbest # %% Print and extract the results print(f"\nOptimized parameter values: {best_params}") print(f"Optimized cost: {best_cost}") # Save the results file_name = f"m1 ({best_cost:.3f}).json" res_out = {"f": best_cost, "x": best_params} Path(file_name).write_text(json.dumps(res_out, cls=NumpyEncoder)) ``` -------------------------------- ### Simulate and Plot SUND Model Scenarios Source: https://isbgroup.eu/sund-toolbox/2.4.1/examples/published/podeus-2024.html This script installs a model, defines multiple activity scenarios, runs simulations for each, and plots the results in a 2x2 grid. ```python import matplotlib.pyplot as plt import numpy as np import sund # %% Install the model by using the SUND function 'install_model' model_name = "alcoholmodel" sund.install_model(f"{model_name}.txt") # %% Load the model by using the sund function 'load_model' model = sund.load_model(f"{model_name}") # %% Create an activity and simulate an alcoholic drink activity = sund.Activity(time_unit=model.time_unit) activity.add_output(type="piecewise_constant", name="EtOH_conc", t=[0, 20], f=[0, 5.1, 0]) activity.add_output( type="piecewise_constant", name="vol_drink_per_time", t=[0, 20], f=[0, 0.05135, 0], ) activity.add_output( type="piecewise_constant", name="kcal_liquid_per_vol", t=[0, 20], f=[0, 129.82, 0], ) activity.add_output(type="constant", name="sex", f=1) activity.add_output(type="constant", name="weight", f=82.66) activity.add_output(type="constant", name="height", f=1.77) # Create a simulation object sim = sund.Simulation( models=model, activities=activity, time_unit=model.time_unit, time_vector=np.arange(0, 250, 0.1), ) sim.simulate() # Plot the results fig = plt.figure(figsize=(18 * (1 / 2.54), 18 * (1 / 2.54))) ax = fig.add_subplot(2, 2, 1) ax.plot( sim.time_vector, sim.feature_values[:, sim.feature_names.index("Blood alcohol concentration")], label="Blood alcohol concentration", ) ax.set_xlabel("Time (min)") ax.set_ylabel("BAC (mg/dL)") ax.legend(edgecolor="None", loc="upper right") # %% Create an activity and simulate an alcoholic drink with food activity = sund.Activity(time_unit=model.time_unit) activity.add_output(type="piecewise_constant", name="EtOH_conc", t=[20, 35], f=[0, 20, 0]) activity.add_output( type="piecewise_constant", name="vol_drink_per_time", t=[20, 35], f=[0, 0.009606, 0], ) activity.add_output( type="piecewise_constant", name="kcal_liquid_per_vol", t=[20, 35], f=[0, 360, 0], ) activity.add_output(type="piecewise_constant", name="kcal_solid", t=[1e-8, 20], f=[0, 700, 0]) activity.add_output(type="constant", name="sex", f=1) activity.add_output(type="constant", name="weight", f=75.80) activity.add_output(type="constant", name="height", f=1.83) # Create a simulation object sim = sund.Simulation( models=model, activities=activity, time_unit=model.time_unit, time_vector=np.arange(0, 400, 0.1), ) sim.simulate() # Plot the results ax = fig.add_subplot(2, 2, 2) ax.plot( sim.time_vector, sim.feature_values[:, sim.feature_names.index("Blood alcohol concentration")], label="Blood alcohol concentration", ) ax.set_xlabel("Time (min)") ax.set_ylabel("BAC (mg/dL)") ax.legend(edgecolor="None", loc="upper right") # %% Create an activity and simulate a non-alcoholic drink activity = sund.Activity(time_unit=model.time_unit) activity.add_output( type="piecewise_constant", name="vol_drink_per_time", t=[0, 3], f=[0, 0.5 / 3, 0], ) activity.add_output(type="piecewise_constant", name="kcal_liquid_per_vol", t=[0, 3], f=[0, 664, 0]) activity.add_output(type="constant", name="sex", f=1) activity.add_output(type="constant", name="weight", f=65.00) activity.add_output(type="constant", name="height", f=1.71) # Create a simulation object sim = sund.Simulation( models=model, activities=activity, time_unit=model.time_unit, time_vector=np.arange(0, 125, 0.1), ) sim.simulate() # Plot the results ax = fig.add_subplot(2, 2, 3) ax.plot( sim.time_vector, sim.feature_values[:, sim.feature_names.index("Gastric volume")], label="Gastric volume", ) ax.set_xlabel("Time (min)") ax.set_ylabel("Volume (mL)") ax.legend(edgecolor="None", loc="upper right") # %% Create an activity and simulate the PEth profile from an alcoholic drink activity = sund.Activity(time_unit=model.time_unit) activity.add_output(type="piecewise_constant", name="EtOH_conc", t=[0, 15], f=[0, 6.41, 0]) activity.add_output( type="piecewise_constant", name="vol_drink_per_time", t=[0, 15], f=[0, 0.0473173, 0], ) activity.add_output( type="piecewise_constant", name="kcal_liquid_per_vol", t=[0, 15], f=[0, 322.3, 0], ) activity.add_output(type="constant", name="sex", f=1) activity.add_output(type="constant", name="weight", f=59.23) activity.add_output(type="constant", name="height", f=1.78) # Create a simulation object sim = sund.Simulation( models=model, activities=activity, time_unit=model.time_unit, time_vector=np.arange(0, 400, 0.1), ) sim.simulate() # Plot the results ax = fig.add_subplot(2, 2, 4) ax.plot(sim.time_vector, sim.feature_values[:, sim.feature_names.index("PEth")], label="PEth") ax.set_xlabel("Time (min)") ax.set_ylabel("PEth (ng/mL)") ax.legend(edgecolor="None", loc="upper right") plt.show() ``` -------------------------------- ### Install specific older version Source: https://isbgroup.eu/sund-toolbox/2.4.1/versions.html Replace with the desired version number to install a specific release from the project's archive. ```shell uv add https://isbgroup.eu/sund-toolbox/releases/sund-.tar.gz ``` ```shell pip install https://isbgroup.eu/sund-toolbox/releases/sund-.tar.gz ``` -------------------------------- ### Initialize Simulation Environment Source: https://isbgroup.eu/sund-toolbox/2.4.1/examples/published/herrgardh_2023/herrgardh_2023.ipynb Imports necessary libraries for data handling and plotting. ```python # %% Imports import matplotlib.pyplot as plt import numpy as np import sund from matplotlib import rcParams ``` -------------------------------- ### Defining model features Source: https://isbgroup.eu/sund-toolbox/2.4.1/functionality/containers.html Example feature definitions that will be prepended with the container name upon assignment. ```text ########## FEATURES glucose = glu uptake = uptake ```