{ "cells": [ { "cell_type": "markdown", "id": "e5ecbcfb", "metadata": {}, "source": [ "# Example 5: Local Sensitivity Analysis — One-At-a-Time (OAT) Sampling \n", "\n", "[(GitHub link)](https://github.com/heberlr/UQ_PhysiCell/tree/main/examples/virus-mac-new/ex5_OAT_example.ipynb)\n", "\n", "This notebook uses **OAT (One-At-a-Time)** sampling to build a simulation database for local sensitivity analysis on the [virus-mac-new](https://github.com/heberlr/UQ_PhysiCell/tree/main/examples/virus-mac-new) model. OAT varies one parameter at a time around a reference point while holding all others fixed — an efficient first screen before committing to a full Sobol analysis (ex3).\n", "\n", "**What you will learn:**\n", "- How `sampler='OAT'` works — `perturbation` values define the % deviations tested around `ref_value`\n", "- Why `qois_info={}` is used here (Mode B — raw MCDS stored) and when that is the right choice (see ex2)\n", "- How to query any QoI from a raw-MCDS database after runs complete using `calculate_qoi_from_db_file`\n", "\n", "**Parameters explored:**\n", "- `mac_phag_rate_infected` — macrophage phagocytosis rate of infected cells\n", "- `mac_motility_bias` — macrophage chemotactic motility bias\n", "- `epi2infected_sat` — saturation of epithelial infection transition\n", "- `epi2infected_hfm` — half-maximum rate of epithelial infection transition\n", "\n", "> **Storage note:** `qois_info={}` stores the full MCDS time series per simulation (Mode B from ex2). OAT is often exploratory, so raw storage lets you compute any QoI post-hoc without re-running." ] }, { "cell_type": "code", "execution_count": 1, "id": "28c6ffe5", "metadata": {}, "outputs": [], "source": [ "import warnings\n", "warnings.filterwarnings('ignore')\n", "\n", "from uq_physicell.model_analysis import ModelAnalysisContext, calculate_qoi_from_db_file\n", "\n", "db_path = \"ex5_Simulations_OAT.db\"\n", "model_config = {\"ini_path\": \"uq_pc_struc.ini\", \"struc_name\": \"Model_struc\"}\n", "\n", "# perturbation values are % deviations applied symmetrically around ref_value\n", "params_info = {\n", " \"mac_phag_rate_infected\": {\"ref_value\": 1.0, \"perturbation\": [1.0, 5.0, 10.0]},\n", " \"mac_motility_bias\": {\"ref_value\": 0.15, \"perturbation\": [1.0, 5.0, 10.0]},\n", " \"epi2infected_sat\": {\"ref_value\": 0.1, \"perturbation\": [1.0, 5.0, 10.0]},\n", " \"epi2infected_hfm\": {\"ref_value\": 0.4, \"perturbation\": [1.0, 5.0, 10.0]},\n", "}\n", "\n", "# Empty qois_info → Mode B: raw MCDS stored, QoIs computed post-hoc (see ex2)\n", "qois_info = {}" ] }, { "cell_type": "markdown", "id": "ecc135fd", "metadata": {}, "source": [ "## Generate samples and run simulations" ] }, { "cell_type": "code", "execution_count": 2, "id": "4817fb39", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Generated 25 samples using OAT\n" ] } ], "source": [ "context = ModelAnalysisContext(db_path, model_config, \"OAT\", params_info, qois_info, num_workers=8)\n", "context.generate_samples()\n", "print(f\"Generated {len(context.dic_samples)} samples using OAT\")" ] }, { "cell_type": "markdown", "id": "789ad199", "metadata": {}, "source": [ "## Run simulations" ] }, { "cell_type": "code", "execution_count": 3, "id": "66de21c0", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Simulations completed and results stored in the database: ex5_Simulations_OAT.db.\n" ] } ], "source": [ "context.run()" ] }, { "cell_type": "markdown", "id": "4cfb5d13", "metadata": {}, "source": [ "## Query any QoI post-hoc from the stored MCDS database" ] }, { "cell_type": "code", "execution_count": 4, "id": "93afcc1f", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
SampleIDtimeReplicateIDinfected_countmac_count
000.00010
100.01010
200.02010
300.03010
400.04010
\n", "
" ], "text/plain": [ " SampleID time ReplicateID infected_count mac_count\n", "0 0 0.0 0 0 10\n", "1 0 0.0 1 0 10\n", "2 0 0.0 2 0 10\n", "3 0 0.0 3 0 10\n", "4 0 0.0 4 0 10" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Define any QoI — no re-simulation required because raw MCDS is in the database\n", "qoi_funcs = {\n", " \"mac_count\": lambda df_cell: len(df_cell[df_cell['cell_type'] == 'macrophage']),\n", " \"infected_count\": lambda df_cell: len(df_cell[df_cell['cell_type'] == 'infected epithelial']),\n", "}\n", "df_qois = calculate_qoi_from_db_file(db_path, qoi_funcs)\n", "display(df_qois.head())" ] }, { "cell_type": "markdown", "id": "14f20380", "metadata": {}, "source": [ "---\n", "**Next:** [ex6](ex6_LHS_example.ipynb) uses Latin Hypercube Sampling (LHS) for a global space-filling design — all parameters vary simultaneously instead of one at a time." ] } ], "metadata": { "kernelspec": { "display_name": "pcvenv", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.3" } }, "nbformat": 4, "nbformat_minor": 5 }