{ "cells": [ { "cell_type": "markdown", "id": "e5ecbcfb", "metadata": {}, "source": [ "# Example 6: Global Parameter Sampling — Latin Hypercube Sampling (LHS) \n", "\n", "[(GitHub link)](https://github.com/heberlr/UQ_PhysiCell/tree/main/examples/virus-mac-new/ex6_LHS_example.ipynb)\n", "\n", "This notebook uses **LHS (Latin Hypercube Sampling)** to build a simulation database on the [virus-mac-new](https://github.com/heberlr/UQ_PhysiCell/tree/main/examples/virus-mac-new) model. LHS divides each parameter range into N equally probable intervals and samples one point per interval, guaranteeing uniform coverage across all dimensions simultaneously.\n", "\n", "**OAT (ex5) vs LHS (ex6):**\n", "| | OAT | LHS |\n", "|---|---|---|\n", "| Varies | One parameter at a time | All parameters simultaneously |\n", "| Reference point | Required (`ref_value`) | Not needed |\n", "| Interactions captured | No | Yes |\n", "| Best for | Quick parameter screening | Space-filling exploration |\n", "\n", "**What you will learn:**\n", "- How `lower_bound` / `upper_bound` define the LHS range and how `N` controls sample count\n", "- Why `qois_info={}` is used here (Mode B — raw MCDS stored) and how to query post-hoc\n", "- How LHS differs from Sobol (ex3) — LHS is space-filling but not optimized for variance decomposition\n", "\n", "**Parameters explored:**\n", "- `mac_phag_rate_infected`, `mac_motility_bias`, `epi2infected_sat`, `epi2infected_hfm`" ] }, { "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 = \"ex6_Simulations_LHS.db\"\n", "model_config = {\"ini_path\": \"uq_pc_struc.ini\", \"struc_name\": \"Model_struc\"}\n", "\n", "# LHS uses only lower_bound and upper_bound — ref_value and perturbation are not needed.\n", "params_info = {\n", " \"mac_phag_rate_infected\": {\"lower_bound\": 0.5, \"upper_bound\": 1.5},\n", " \"mac_motility_bias\": {\"lower_bound\": 0.075, \"upper_bound\": 0.225},\n", " \"epi2infected_sat\": {\"lower_bound\": 0.05, \"upper_bound\": 0.15},\n", " \"epi2infected_hfm\": {\"lower_bound\": 0.2, \"upper_bound\": 0.6},\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 20 samples using LHS\n" ] } ], "source": [ "context = ModelAnalysisContext(db_path, model_config, \"Latin hypercube sampling (LHS)\", params_info, qois_info, num_workers=8)\n", "context.generate_samples(N=20)\n", "print(f\"Generated {len(context.dic_samples)} samples using LHS\")" ] }, { "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: ex6_Simulations_LHS.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": "4003f30e", "metadata": {}, "source": [ "---\n", "**Next:** [ex7](ex7_Calib_BO.ipynb) uses Bayesian Optimization to calibrate model parameters against observed data — a goal-directed search compared to the space-filling approach used here." ] } ], "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 }