Example 6: Global Parameter Sampling — Latin Hypercube Sampling (LHS)

(GitHub link)

This notebook uses LHS (Latin Hypercube Sampling) to build a simulation database on the 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.

OAT (ex5) vs LHS (ex6):

OAT

LHS

Varies

One parameter at a time

All parameters simultaneously

Reference point

Required (ref_value)

Not needed

Interactions captured

No

Yes

Best for

Quick parameter screening

Space-filling exploration

What you will learn:

  • How lower_bound / upper_bound define the LHS range and how N controls sample count

  • Why qois_info={} is used here (Mode B — raw MCDS stored) and how to query post-hoc

  • How LHS differs from Sobol (ex3) — LHS is space-filling but not optimized for variance decomposition

Parameters explored:

  • mac_phag_rate_infected, mac_motility_bias, epi2infected_sat, epi2infected_hfm

import warnings
warnings.filterwarnings('ignore')

from uq_physicell.model_analysis import ModelAnalysisContext, calculate_qoi_from_db_file

db_path = "ex6_Simulations_LHS.db"
model_config = {"ini_path": "uq_pc_struc.ini", "struc_name": "Model_struc"}

# LHS uses only lower_bound and upper_bound — ref_value and perturbation are not needed.
params_info = {
    "mac_phag_rate_infected": {"lower_bound": 0.5,   "upper_bound": 1.5},
    "mac_motility_bias":      {"lower_bound": 0.075, "upper_bound": 0.225},
    "epi2infected_sat":       {"lower_bound": 0.05,  "upper_bound": 0.15},
    "epi2infected_hfm":       {"lower_bound": 0.2,   "upper_bound": 0.6},
}

# Empty qois_info → Mode B: raw MCDS stored, QoIs computed post-hoc (see ex2)
qois_info = {}

Generate samples and run simulations

context = ModelAnalysisContext(db_path, model_config, "Latin hypercube sampling (LHS)", params_info, qois_info, num_workers=8)
context.generate_samples(N=20)
print(f"Generated {len(context.dic_samples)} samples using LHS")
Generated 20 samples using LHS

Run simulations

context.run()
Simulations completed and results stored in the database: ex6_Simulations_LHS.db.

Query any QoI post-hoc from the stored MCDS database

# Define any QoI — no re-simulation required because raw MCDS is in the database
qoi_funcs = {
    "mac_count":      lambda df_cell: len(df_cell[df_cell['cell_type'] == 'macrophage']),
    "infected_count": lambda df_cell: len(df_cell[df_cell['cell_type'] == 'infected epithelial']),
}
df_qois = calculate_qoi_from_db_file(db_path, qoi_funcs)
display(df_qois.head())
SampleID time ReplicateID infected_count mac_count
0 0 0.0 0 0 10
1 0 0.0 1 0 10
2 0 0.0 2 0 10
3 0 0.0 3 0 10
4 0 0.0 4 0 10

Next: ex7 uses Bayesian Optimization to calibrate model parameters against observed data — a goal-directed search compared to the space-filling approach used here.