Example 9: Model Calibration — Bayesian Optimization with Warm Start

(GitHub link)

This notebook calibrates a custom PhysiCell model using Bayesian Optimization (BO) warm-started from an existing simulation database. Instead of generating random initial samples from scratch (as in ex7), this workflow reuses a database already built from a sensitivity analysis or exploration run (via the GUI or the SA script), making the first Gaussian Process fit much more informative.

Ex7 vs Ex9:

ex7

ex9

Initial samples

Generated from scratch (num_initial_samples)

Loaded from existing SA database (db_path_initial_samples)

GP quality at start

Low — random coverage

Higher — informed by prior runs

Best for

First-time calibration

Calibrating after SA is already done

What you will learn:

  • How to set bo_options["db_path_initial_samples"] to seed BO from an existing database

  • How to run post-calibration simulations at Pareto front points using ModelAnalysisContext and set_samples()

  • How to visualize cell spatial distributions from calibrated parameter sets using plot_cells_2D

Ground truth (from ObsData.csv):

  • cell_cycle_entry = 1440.0

  • apoptosis_rate = 5.787×10⁻⁵

import warnings
import matplotlib.pyplot as plt
warnings.filterwarnings('ignore')

from uq_physicell.bo import CalibrationContext, run_bayesian_optimization

dic_real_value = {"cell_cycle_entry": 1440.0, "apoptosis_rate": 5.787e-05}

db_path = "Calib_BO.db"
obs_data_path = "ObsData.csv"

model_config = {"ini_path": "uq_config.ini", "struc_name": "ModelA"}

# df_cell → cell DataFrame, mcds_ts → full time series (see ex1 for the full dispatch table)
qoi_functions = {
    "live_cell_count":      lambda df_cell: len(df_cell[df_cell['dead'] == False]),
    "sum_dead_cell_count":  lambda mcds_ts: sum(len(mcds.get_cell_df()[mcds.get_cell_df()['dead'] == True]) for mcds in mcds_ts),
}

obs_data_columns = {
    "time":               "Time",
    "live_cell_count":    "Live_Cells",
    "sum_dead_cell_count":"Sum_Dead_Cells",
}

bo_options = {
    "db_path_initial_samples":  "Simulations.db",  # warm-start GP with samples from an existing SA database
    "num_iterations":           30,
    "batch_size_per_iteration": 1,
    "max_workers":              5,
}
# Create the calibration context
calib_context = CalibrationContext(
    db_path=db_path,
    obsData=obs_data_path,
    obsData_columns=obs_data_columns,
    model_config=model_config,
    qoi_functions=qoi_functions,
    bo_options=bo_options,
)
# Run the Bayesian Optimization calibration
run_bayesian_optimization(calib_context)
2026-01-23 10:33:09,288 - INFO - 🧪 Initial samples will be generated from existing database at Simulations.db.
2026-01-23 10:33:09,290 - INFO - 📊 Estimating weights from observational data ranges:
  📈 live_cell_count - weight: 2.13e-05 (range=1.52e+03)
  📈 sum_dead_cell_count - weight: 9.58e-04 (range=1.04e+03)

2026-01-23 10:33:09,291 - INFO - 🔧 CalibrationContext initialized with 5 max workers, 5 inner workers, and 1 outer workers.
2026-01-23 10:33:09,291 - INFO - 🆕 Starting fresh optimization with database: Calib_BO.db
2026-01-23 10:33:09,294 - INFO - 🧪 Generating initial samples from Simulations.db...
2026-01-23 10:33:47,443 - INFO - 🔬 Detected multiple QoIs - using multi-objective Bayesian optimization loop.
2026-01-23 10:33:47,445 - INFO - ============================================================
2026-01-23 10:33:47,446 - INFO - 🔄 Multi-Objective BO Iteration 1/30
2026-01-23 10:33:47,446 - INFO - ============================================================
2026-01-23 10:33:47,446 - INFO - 🔧 Fitting Gaussian Process models...
2026-01-23 10:33:48,061 - INFO - 🎯 Optimizing acquisition function...
2026-01-23 10:33:48,931 - INFO - 📊 Evaluating 1 new candidate(s)...
2026-01-23 10:33:48,931 - INFO - 	 Candidate 1: {'cell_cycle_entry': 1603.602283694463, 'apoptosis_rate': 6.380004e-05}
2026-01-23 10:37:59,859 - INFO - 	 Results for Sample ID 48: Objectives = {'live_cell_count': np.float64(0.09565603136172476), 'sum_dead_cell_count': np.float64(0.17248324760752176)}, Noise Std = {'live_cell_count': np.float64(0.04778658409371317), 'sum_dead_cell_count': np.float64(0.11504953933733367)}
2026-01-23 10:37:59,866 - INFO - 📊 Iteration 1 Sample(s) [48] : Hypervolume = 0.00028663075785369306
2026-01-23 10:37:59,866 - INFO - ✅ Completed iteration 1/30 - Total samples: 49
2026-01-23 10:37:59,866 - INFO - 🎯 Best fitness values:
2026-01-23 10:37:59,867 - INFO - 	 Best parameters for best fitness of live_cell_count (sample 39): {'cell_cycle_entry': 1526.73287646256, 'apoptosis_rate': 5.6972530886514257e-05}
2026-01-23 10:37:59,867 - INFO - 	 Fitness: {'live_cell_count': 0.8045753209307664, 'sum_dead_cell_count': 0.1938266989501782}.
2026-01-23 10:37:59,867 - INFO - 	 Best parameters for best fitness of sum_dead_cell_count (sample 4): {'cell_cycle_entry': 1559.1182049626123, 'apoptosis_rate': 5.98522630694583e-05}
2026-01-23 10:37:59,867 - INFO - 	 Fitness: {'live_cell_count': 0.5649144394341963, 'sum_dead_cell_count': 0.8559025559873279}.
2026-01-23 10:37:59,867 - INFO - ============================================================
2026-01-23 10:37:59,868 - INFO - 🔄 Multi-Objective BO Iteration 2/30
2026-01-23 10:37:59,868 - INFO - ============================================================
2026-01-23 10:37:59,868 - INFO - 🔧 Fitting Gaussian Process models...
2026-01-23 10:37:59,910 - INFO - 🎯 Optimizing acquisition function...
2026-01-23 10:38:01,872 - INFO - 📊 Evaluating 1 new candidate(s)...
2026-01-23 10:38:01,873 - INFO - 	 Candidate 1: {'cell_cycle_entry': 1527.1875183509114, 'apoptosis_rate': 4.2533360000000006e-05}
2026-01-23 10:42:26,900 - INFO - 	 Results for Sample ID 49: Objectives = {'live_cell_count': np.float64(0.42922761734405845), 'sum_dead_cell_count': np.float64(1.0767434854920378e-17)}, Noise Std = {'live_cell_count': np.float64(0.11503147780043149), 'sum_dead_cell_count': np.float64(8.791573744404202e-18)}
2026-01-23 10:42:26,906 - INFO - 📊 Iteration 2 Sample(s) [49] : Hypervolume = 0.00030567307827148425
2026-01-23 10:42:26,906 - INFO - ✅ Completed iteration 2/30 - Total samples: 50
2026-01-23 10:42:26,907 - INFO - 🎯 Best fitness values:
2026-01-23 10:42:26,907 - INFO - 	 Best parameters for best fitness of live_cell_count (sample 39): {'cell_cycle_entry': 1526.73287646256, 'apoptosis_rate': 5.6972530886514257e-05}
2026-01-23 10:42:26,907 - INFO - 	 Fitness: {'live_cell_count': 0.8045753209307664, 'sum_dead_cell_count': 0.1938266989501782}.
2026-01-23 10:42:26,907 - INFO - 	 Best parameters for best fitness of sum_dead_cell_count (sample 4): {'cell_cycle_entry': 1559.1182049626123, 'apoptosis_rate': 5.98522630694583e-05}
2026-01-23 10:42:26,907 - INFO - 	 Fitness: {'live_cell_count': 0.5649144394341963, 'sum_dead_cell_count': 0.8559025559873279}.
2026-01-23 10:42:26,908 - INFO - ============================================================
2026-01-23 10:42:26,908 - INFO - 🔄 Multi-Objective BO Iteration 3/30
2026-01-23 10:42:26,908 - INFO - ============================================================
2026-01-23 10:42:26,908 - INFO - 🔧 Fitting Gaussian Process models...
2026-01-23 10:42:26,945 - INFO - 🎯 Optimizing acquisition function...
2026-01-23 10:42:27,445 - INFO - 📊 Evaluating 1 new candidate(s)...
2026-01-23 10:42:27,445 - INFO - 	 Candidate 1: {'cell_cycle_entry': 1111.111112, 'apoptosis_rate': 4.2533360000000006e-05}
2026-01-23 10:48:07,265 - INFO - 	 Results for Sample ID 50: Objectives = {'live_cell_count': np.float64(2.143225366986528e-21), 'sum_dead_cell_count': np.float64(0.0172560142824391)}, Noise Std = {'live_cell_count': np.float64(4.277440812371138e-21), 'sum_dead_cell_count': np.float64(0.03437274631172815)}
2026-01-23 10:48:07,271 - INFO - 📊 Iteration 3 Sample(s) [50] : Hypervolume = 0.0002809308482624621
2026-01-23 10:48:07,271 - INFO - ✅ Completed iteration 3/30 - Total samples: 51
2026-01-23 10:48:07,271 - INFO - 🎯 Best fitness values:
2026-01-23 10:48:07,272 - INFO - 	 Best parameters for best fitness of live_cell_count (sample 39): {'cell_cycle_entry': 1526.73287646256, 'apoptosis_rate': 5.6972530886514257e-05}
2026-01-23 10:48:07,272 - INFO - 	 Fitness: {'live_cell_count': 0.8045753209307664, 'sum_dead_cell_count': 0.1938266989501782}.
2026-01-23 10:48:07,272 - INFO - 	 Best parameters for best fitness of sum_dead_cell_count (sample 4): {'cell_cycle_entry': 1559.1182049626123, 'apoptosis_rate': 5.98522630694583e-05}
2026-01-23 10:48:07,272 - INFO - 	 Fitness: {'live_cell_count': 0.5649144394341963, 'sum_dead_cell_count': 0.8559025559873279}.
2026-01-23 10:48:07,273 - INFO - ============================================================
2026-01-23 10:48:07,273 - INFO - 🔄 Multi-Objective BO Iteration 4/30
2026-01-23 10:48:07,273 - INFO - ============================================================
2026-01-23 10:48:07,273 - INFO - 🔧 Fitting Gaussian Process models...
2026-01-23 10:48:07,309 - INFO - 🎯 Optimizing acquisition function...
2026-01-23 10:48:08,440 - INFO - 📊 Evaluating 1 new candidate(s)...
2026-01-23 10:48:08,441 - INFO - 	 Candidate 1: {'cell_cycle_entry': 1552.533384457143, 'apoptosis_rate': 6.380004e-05}
2026-01-23 10:52:41,491 - INFO - 	 Results for Sample ID 51: Objectives = {'live_cell_count': np.float64(0.20673090660247198), 'sum_dead_cell_count': np.float64(0.06460878180756305)}, Noise Std = {'live_cell_count': np.float64(0.15208810786983498), 'sum_dead_cell_count': np.float64(0.1285811116522596)}
2026-01-23 10:52:41,497 - INFO - 📊 Iteration 4 Sample(s) [51] : Hypervolume = 0.00027386825124005906
2026-01-23 10:52:41,497 - INFO - ✅ Completed iteration 4/30 - Total samples: 52
2026-01-23 10:52:41,497 - INFO - 🎯 Best fitness values:
2026-01-23 10:52:41,497 - INFO - 	 Best parameters for best fitness of live_cell_count (sample 39): {'cell_cycle_entry': 1526.73287646256, 'apoptosis_rate': 5.6972530886514257e-05}
2026-01-23 10:52:41,498 - INFO - 	 Fitness: {'live_cell_count': 0.8045753209307664, 'sum_dead_cell_count': 0.1938266989501782}.
2026-01-23 10:52:41,498 - INFO - 	 Best parameters for best fitness of sum_dead_cell_count (sample 4): {'cell_cycle_entry': 1559.1182049626123, 'apoptosis_rate': 5.98522630694583e-05}
2026-01-23 10:52:41,498 - INFO - 	 Fitness: {'live_cell_count': 0.5649144394341963, 'sum_dead_cell_count': 0.8559025559873279}.
2026-01-23 10:52:41,498 - INFO - ============================================================
2026-01-23 10:52:41,498 - INFO - 🔄 Multi-Objective BO Iteration 5/30
2026-01-23 10:52:41,499 - INFO - ============================================================
2026-01-23 10:52:41,499 - INFO - 🔧 Fitting Gaussian Process models...
2026-01-23 10:52:41,537 - INFO - 🎯 Optimizing acquisition function...
2026-01-23 10:52:42,396 - INFO - 📊 Evaluating 1 new candidate(s)...
2026-01-23 10:52:42,397 - INFO - 	 Candidate 1: {'cell_cycle_entry': 1593.2674885369477, 'apoptosis_rate': 4.2533360000000006e-05}
2026-01-23 10:57:08,322 - INFO - 	 Results for Sample ID 52: Objectives = {'live_cell_count': np.float64(0.5119701889031594), 'sum_dead_cell_count': np.float64(4.6154360352442384e-23)}, Noise Std = {'live_cell_count': np.float64(0.2873488017035282), 'sum_dead_cell_count': np.float64(5.652731613396668e-23)}
2026-01-23 10:57:08,328 - INFO - 📊 Iteration 5 Sample(s) [52] : Hypervolume = 0.0002628567694836428
2026-01-23 10:57:08,328 - INFO - ✅ Completed iteration 5/30 - Total samples: 53
2026-01-23 10:57:08,328 - INFO - 🎯 Best fitness values:
2026-01-23 10:57:08,329 - INFO - 	 Best parameters for best fitness of live_cell_count (sample 39): {'cell_cycle_entry': 1526.73287646256, 'apoptosis_rate': 5.6972530886514257e-05}
2026-01-23 10:57:08,329 - INFO - 	 Fitness: {'live_cell_count': 0.8045753209307664, 'sum_dead_cell_count': 0.1938266989501782}.
2026-01-23 10:57:08,329 - INFO - 	 Best parameters for best fitness of sum_dead_cell_count (sample 4): {'cell_cycle_entry': 1559.1182049626123, 'apoptosis_rate': 5.98522630694583e-05}
2026-01-23 10:57:08,329 - INFO - 	 Fitness: {'live_cell_count': 0.5649144394341963, 'sum_dead_cell_count': 0.8559025559873279}.
2026-01-23 10:57:08,329 - INFO - ============================================================
2026-01-23 10:57:08,329 - INFO - 🔄 Multi-Objective BO Iteration 6/30
2026-01-23 10:57:08,330 - INFO - ============================================================
2026-01-23 10:57:08,330 - INFO - 🔧 Fitting Gaussian Process models...
2026-01-23 10:57:08,380 - INFO - 🎯 Optimizing acquisition function...
2026-01-23 10:57:10,008 - INFO - 📊 Evaluating 1 new candidate(s)...
2026-01-23 10:57:10,008 - INFO - 	 Candidate 1: {'cell_cycle_entry': 1483.8772480461284, 'apoptosis_rate': 4.2533360000000006e-05}
2026-01-23 11:01:34,922 - INFO - 	 Results for Sample ID 53: Objectives = {'live_cell_count': np.float64(0.5021531014110332), 'sum_dead_cell_count': np.float64(3.5826215513083285e-23)}, Noise Std = {'live_cell_count': np.float64(0.2610644771896203), 'sum_dead_cell_count': np.float64(7.158274408979336e-23)}
2026-01-23 11:01:34,928 - INFO - 📊 Iteration 6 Sample(s) [53] : Hypervolume = 0.0002533657797338559
2026-01-23 11:01:34,928 - INFO - ✅ Completed iteration 6/30 - Total samples: 54
2026-01-23 11:01:34,928 - INFO - 🎯 Best fitness values:
2026-01-23 11:01:34,929 - INFO - 	 Best parameters for best fitness of live_cell_count (sample 39): {'cell_cycle_entry': 1526.73287646256, 'apoptosis_rate': 5.6972530886514257e-05}
2026-01-23 11:01:34,929 - INFO - 	 Fitness: {'live_cell_count': 0.8045753209307664, 'sum_dead_cell_count': 0.1938266989501782}.
2026-01-23 11:01:34,929 - INFO - 	 Best parameters for best fitness of sum_dead_cell_count (sample 4): {'cell_cycle_entry': 1559.1182049626123, 'apoptosis_rate': 5.98522630694583e-05}
2026-01-23 11:01:34,929 - INFO - 	 Fitness: {'live_cell_count': 0.5649144394341963, 'sum_dead_cell_count': 0.8559025559873279}.
2026-01-23 11:01:34,929 - INFO - ============================================================
2026-01-23 11:01:34,930 - INFO - 🔄 Multi-Objective BO Iteration 7/30
2026-01-23 11:01:34,930 - INFO - ============================================================
2026-01-23 11:01:34,930 - INFO - 🔧 Fitting Gaussian Process models...
2026-01-23 11:01:34,968 - INFO - 🎯 Optimizing acquisition function...
2026-01-23 11:01:35,751 - INFO - 📊 Evaluating 1 new candidate(s)...
2026-01-23 11:01:35,752 - INFO - 	 Candidate 1: {'cell_cycle_entry': 1536.4707828138417, 'apoptosis_rate': 4.2533360000000006e-05}
2026-01-23 11:05:49,690 - INFO - 	 Results for Sample ID 54: Objectives = {'live_cell_count': np.float64(0.6078705739800745), 'sum_dead_cell_count': np.float64(8.093369207297318e-29)}, Noise Std = {'live_cell_count': np.float64(0.30932936297775737), 'sum_dead_cell_count': np.float64(1.5823702325293272e-28)}
2026-01-23 11:05:49,695 - INFO - 📊 Iteration 7 Sample(s) [54] : Hypervolume = 0.0002548017082026973
2026-01-23 11:05:49,696 - INFO - ✅ Completed iteration 7/30 - Total samples: 55
2026-01-23 11:05:49,696 - INFO - 🎯 Best fitness values:
2026-01-23 11:05:49,696 - INFO - 	 Best parameters for best fitness of live_cell_count (sample 39): {'cell_cycle_entry': 1526.73287646256, 'apoptosis_rate': 5.6972530886514257e-05}
2026-01-23 11:05:49,696 - INFO - 	 Fitness: {'live_cell_count': 0.8045753209307664, 'sum_dead_cell_count': 0.1938266989501782}.
2026-01-23 11:05:49,697 - INFO - 	 Best parameters for best fitness of sum_dead_cell_count (sample 4): {'cell_cycle_entry': 1559.1182049626123, 'apoptosis_rate': 5.98522630694583e-05}
2026-01-23 11:05:49,697 - INFO - 	 Fitness: {'live_cell_count': 0.5649144394341963, 'sum_dead_cell_count': 0.8559025559873279}.
2026-01-23 11:05:49,697 - INFO - ============================================================
2026-01-23 11:05:49,697 - INFO - 🔄 Multi-Objective BO Iteration 8/30
2026-01-23 11:05:49,697 - INFO - ============================================================
2026-01-23 11:05:49,697 - INFO - 🔧 Fitting Gaussian Process models...
2026-01-23 11:05:49,737 - INFO - 🎯 Optimizing acquisition function...
2026-01-23 11:05:51,008 - INFO - 📊 Evaluating 1 new candidate(s)...
2026-01-23 11:05:51,008 - INFO - 	 Candidate 1: {'cell_cycle_entry': 1574.55703339499, 'apoptosis_rate': 6.380004e-05}
2026-01-23 11:09:47,295 - INFO - 	 Results for Sample ID 55: Objectives = {'live_cell_count': np.float64(0.05700898892156454), 'sum_dead_cell_count': np.float64(0.24711873086190436)}, Noise Std = {'live_cell_count': np.float64(0.0679507557761496), 'sum_dead_cell_count': np.float64(0.3093394583779661)}
2026-01-23 11:09:47,300 - INFO - 📊 Iteration 8 Sample(s) [55] : Hypervolume = 0.0002582194213799206
2026-01-23 11:09:47,301 - INFO - ✅ Completed iteration 8/30 - Total samples: 56
2026-01-23 11:09:47,301 - INFO - 🎯 Best fitness values:
2026-01-23 11:09:47,301 - INFO - 	 Best parameters for best fitness of live_cell_count (sample 39): {'cell_cycle_entry': 1526.73287646256, 'apoptosis_rate': 5.6972530886514257e-05}
2026-01-23 11:09:47,301 - INFO - 	 Fitness: {'live_cell_count': 0.8045753209307664, 'sum_dead_cell_count': 0.1938266989501782}.
2026-01-23 11:09:47,302 - INFO - 	 Best parameters for best fitness of sum_dead_cell_count (sample 4): {'cell_cycle_entry': 1559.1182049626123, 'apoptosis_rate': 5.98522630694583e-05}
2026-01-23 11:09:47,302 - INFO - 	 Fitness: {'live_cell_count': 0.5649144394341963, 'sum_dead_cell_count': 0.8559025559873279}.
2026-01-23 11:09:47,302 - INFO - ============================================================
2026-01-23 11:09:47,302 - INFO - 🔄 Multi-Objective BO Iteration 9/30
2026-01-23 11:09:47,303 - INFO - ============================================================
2026-01-23 11:09:47,303 - INFO - 🔧 Fitting Gaussian Process models...
2026-01-23 11:09:47,340 - INFO - 🎯 Optimizing acquisition function...
2026-01-23 11:09:48,175 - INFO - 📊 Evaluating 1 new candidate(s)...
2026-01-23 11:09:48,175 - INFO - 	 Candidate 1: {'cell_cycle_entry': 1533.1293572025725, 'apoptosis_rate': 5.159503945870137e-05}
2026-01-23 11:13:53,753 - INFO - 	 Results for Sample ID 56: Objectives = {'live_cell_count': np.float64(0.35242541634338365), 'sum_dead_cell_count': np.float64(0.0003388988821183495)}, Noise Std = {'live_cell_count': np.float64(0.31049349064106385), 'sum_dead_cell_count': np.float64(0.0006777937335861422)}
2026-01-23 11:13:53,758 - INFO - 📊 Iteration 9 Sample(s) [56] : Hypervolume = 0.00022220526473593422
2026-01-23 11:13:53,758 - INFO - ✅ Completed iteration 9/30 - Total samples: 57
2026-01-23 11:13:53,759 - INFO - 🎯 Best fitness values:
2026-01-23 11:13:53,759 - INFO - 	 Best parameters for best fitness of live_cell_count (sample 39): {'cell_cycle_entry': 1526.73287646256, 'apoptosis_rate': 5.6972530886514257e-05}
2026-01-23 11:13:53,759 - INFO - 	 Fitness: {'live_cell_count': 0.8045753209307664, 'sum_dead_cell_count': 0.1938266989501782}.
2026-01-23 11:13:53,759 - INFO - 	 Best parameters for best fitness of sum_dead_cell_count (sample 4): {'cell_cycle_entry': 1559.1182049626123, 'apoptosis_rate': 5.98522630694583e-05}
2026-01-23 11:13:53,760 - INFO - 	 Fitness: {'live_cell_count': 0.5649144394341963, 'sum_dead_cell_count': 0.8559025559873279}.
2026-01-23 11:13:53,760 - INFO - ============================================================
2026-01-23 11:13:53,760 - INFO - 🔄 Multi-Objective BO Iteration 10/30
2026-01-23 11:13:53,760 - INFO - ============================================================
2026-01-23 11:13:53,760 - INFO - 🔧 Fitting Gaussian Process models...
2026-01-23 11:13:53,795 - INFO - 🎯 Optimizing acquisition function...
2026-01-23 11:13:54,830 - INFO - 📊 Evaluating 1 new candidate(s)...
2026-01-23 11:13:54,831 - INFO - 	 Candidate 1: {'cell_cycle_entry': 1666.6666679999998, 'apoptosis_rate': 6.380004e-05}
2026-01-23 11:17:52,373 - INFO - 	 Results for Sample ID 57: Objectives = {'live_cell_count': np.float64(0.0013592081127853848), 'sum_dead_cell_count': np.float64(0.2092976922757635)}, Noise Std = {'live_cell_count': np.float64(0.0005430648491345109), 'sum_dead_cell_count': np.float64(0.22680735627176382)}
2026-01-23 11:17:52,379 - INFO - 📊 Iteration 10 Sample(s) [57] : Hypervolume = 0.00023656625721832448
2026-01-23 11:17:52,379 - INFO - 🔍 Analyzing convergence...
2026-01-23 11:17:52,380 - WARNING - ⚠️  High noise detected (max 87.5%) - using relaxed convergence criteria
2026-01-23 11:17:52,382 - INFO - 	📋 Convergence Status: in_progress
2026-01-23 11:17:52,382 - INFO - 	💡 Reason: Slow but steady progress
2026-01-23 11:17:52,382 - INFO - 	🎯 Confidence: 38.69%
2026-01-23 11:17:52,382 - INFO - 	📊 Noise level: max=87.5%, avg=69.6%, SNR=1.1
2026-01-23 11:17:52,382 - INFO - ✅ Completed iteration 10/30 - Total samples: 58
2026-01-23 11:17:52,383 - INFO - 🎯 Best fitness values:
2026-01-23 11:17:52,383 - INFO - 	 Best parameters for best fitness of live_cell_count (sample 39): {'cell_cycle_entry': 1526.73287646256, 'apoptosis_rate': 5.6972530886514257e-05}
2026-01-23 11:17:52,383 - INFO - 	 Fitness: {'live_cell_count': 0.8045753209307664, 'sum_dead_cell_count': 0.1938266989501782}.
2026-01-23 11:17:52,383 - INFO - 	 Best parameters for best fitness of sum_dead_cell_count (sample 4): {'cell_cycle_entry': 1559.1182049626123, 'apoptosis_rate': 5.98522630694583e-05}
2026-01-23 11:17:52,383 - INFO - 	 Fitness: {'live_cell_count': 0.5649144394341963, 'sum_dead_cell_count': 0.8559025559873279}.
2026-01-23 11:17:52,383 - INFO - ============================================================
2026-01-23 11:17:52,384 - INFO - 🔄 Multi-Objective BO Iteration 11/30
2026-01-23 11:17:52,384 - INFO - ============================================================
2026-01-23 11:17:52,384 - INFO - 🔧 Fitting Gaussian Process models...
2026-01-23 11:17:52,420 - INFO - 🎯 Optimizing acquisition function...
2026-01-23 11:17:53,615 - INFO - 📊 Evaluating 1 new candidate(s)...
2026-01-23 11:17:53,616 - INFO - 	 Candidate 1: {'cell_cycle_entry': 1666.6666679999998, 'apoptosis_rate': 4.2533360000000006e-05}
2026-01-23 11:22:02,684 - INFO - 	 Results for Sample ID 58: Objectives = {'live_cell_count': np.float64(0.21559367780621783), 'sum_dead_cell_count': np.float64(1.4381934775222066e-36)}, Noise Std = {'live_cell_count': np.float64(0.23437888241787158), 'sum_dead_cell_count': np.float64(2.8763869547161035e-36)}
2026-01-23 11:22:02,692 - INFO - 📊 Iteration 11 Sample(s) [58] : Hypervolume = 0.00022848148453930982
2026-01-23 11:22:02,692 - INFO - 🔍 Analyzing convergence...
2026-01-23 11:22:02,693 - WARNING - ⚠️  High noise detected (max 87.5%) - using relaxed convergence criteria
2026-01-23 11:22:02,693 - INFO - 	📋 Convergence Status: in_progress
2026-01-23 11:22:02,694 - INFO - 	💡 Reason: Normal optimization progress
2026-01-23 11:22:02,694 - INFO - 	🎯 Confidence: 38.38%
2026-01-23 11:22:02,694 - INFO - 	📊 Noise level: max=87.5%, avg=70.0%, SNR=1.1
2026-01-23 11:22:02,694 - INFO - ✅ Completed iteration 11/30 - Total samples: 59
2026-01-23 11:22:02,694 - INFO - 🎯 Best fitness values:
2026-01-23 11:22:02,695 - INFO - 	 Best parameters for best fitness of live_cell_count (sample 39): {'cell_cycle_entry': 1526.73287646256, 'apoptosis_rate': 5.6972530886514257e-05}
2026-01-23 11:22:02,695 - INFO - 	 Fitness: {'live_cell_count': 0.8045753209307664, 'sum_dead_cell_count': 0.1938266989501782}.
2026-01-23 11:22:02,695 - INFO - 	 Best parameters for best fitness of sum_dead_cell_count (sample 4): {'cell_cycle_entry': 1559.1182049626123, 'apoptosis_rate': 5.98522630694583e-05}
2026-01-23 11:22:02,695 - INFO - 	 Fitness: {'live_cell_count': 0.5649144394341963, 'sum_dead_cell_count': 0.8559025559873279}.
2026-01-23 11:22:02,696 - INFO - ============================================================
2026-01-23 11:22:02,696 - INFO - 🔄 Multi-Objective BO Iteration 12/30
2026-01-23 11:22:02,696 - INFO - ============================================================
2026-01-23 11:22:02,696 - INFO - 🔧 Fitting Gaussian Process models...
2026-01-23 11:22:02,733 - INFO - 🎯 Optimizing acquisition function...
2026-01-23 11:22:04,323 - INFO - 📊 Evaluating 1 new candidate(s)...
2026-01-23 11:22:04,324 - INFO - 	 Candidate 1: {'cell_cycle_entry': 1446.598914995137, 'apoptosis_rate': 6.380004e-05}
2026-01-23 11:26:33,086 - INFO - 	 Results for Sample ID 59: Objectives = {'live_cell_count': np.float64(0.6889960141012972), 'sum_dead_cell_count': np.float64(0.006095627883168007)}, Noise Std = {'live_cell_count': np.float64(0.09823206242052736), 'sum_dead_cell_count': np.float64(0.012115271298535324)}
2026-01-23 11:26:33,093 - INFO - 📊 Iteration 12 Sample(s) [59] : Hypervolume = 0.0002275179743481401
2026-01-23 11:26:33,093 - INFO - 🔍 Analyzing convergence...
2026-01-23 11:26:33,094 - WARNING - ⚠️  High noise detected (max 87.6%) - using relaxed convergence criteria
2026-01-23 11:26:33,094 - INFO - 	📋 Convergence Status: in_progress
2026-01-23 11:26:33,094 - INFO - 	💡 Reason: Slow but steady progress
2026-01-23 11:26:33,094 - INFO - 	🎯 Confidence: 40.52%
2026-01-23 11:26:33,095 - INFO - 	📊 Noise level: max=87.6%, avg=69.1%, SNR=1.1
2026-01-23 11:26:33,095 - INFO - ✅ Completed iteration 12/30 - Total samples: 60
2026-01-23 11:26:33,095 - INFO - 🎯 Best fitness values:
2026-01-23 11:26:33,095 - INFO - 	 Best parameters for best fitness of live_cell_count (sample 39): {'cell_cycle_entry': 1526.73287646256, 'apoptosis_rate': 5.6972530886514257e-05}
2026-01-23 11:26:33,095 - INFO - 	 Fitness: {'live_cell_count': 0.8045753209307664, 'sum_dead_cell_count': 0.1938266989501782}.
2026-01-23 11:26:33,096 - INFO - 	 Best parameters for best fitness of sum_dead_cell_count (sample 4): {'cell_cycle_entry': 1559.1182049626123, 'apoptosis_rate': 5.98522630694583e-05}
2026-01-23 11:26:33,096 - INFO - 	 Fitness: {'live_cell_count': 0.5649144394341963, 'sum_dead_cell_count': 0.8559025559873279}.
2026-01-23 11:26:33,096 - INFO - ============================================================
2026-01-23 11:26:33,096 - INFO - 🔄 Multi-Objective BO Iteration 13/30
2026-01-23 11:26:33,096 - INFO - ============================================================
2026-01-23 11:26:33,097 - INFO - 🔧 Fitting Gaussian Process models...
2026-01-23 11:26:33,133 - INFO - 🎯 Optimizing acquisition function...
2026-01-23 11:26:34,567 - INFO - 📊 Evaluating 1 new candidate(s)...
2026-01-23 11:26:34,567 - INFO - 	 Candidate 1: {'cell_cycle_entry': 1488.7621018135542, 'apoptosis_rate': 6.380004e-05}
2026-01-23 11:31:01,066 - INFO - 	 Results for Sample ID 60: Objectives = {'live_cell_count': np.float64(0.5802349255185524), 'sum_dead_cell_count': np.float64(0.002141530637803453)}, Noise Std = {'live_cell_count': np.float64(0.22483294126688044), 'sum_dead_cell_count': np.float64(0.0026256545498981525)}
2026-01-23 11:31:01,073 - INFO - 📊 Iteration 13 Sample(s) [60] : Hypervolume = 0.0003004261819983782
2026-01-23 11:31:01,074 - INFO - 🔍 Analyzing convergence...
2026-01-23 11:31:01,075 - WARNING - ⚠️  High noise detected (max 87.6%) - using relaxed convergence criteria
2026-01-23 11:31:01,075 - INFO - 	📋 Convergence Status: in_progress
2026-01-23 11:31:01,076 - INFO - 	💡 Reason: Normal optimization progress
2026-01-23 11:31:01,076 - INFO - 	🎯 Confidence: 40.29%
2026-01-23 11:31:01,076 - INFO - 	📊 Noise level: max=87.6%, avg=68.9%, SNR=1.1
2026-01-23 11:31:01,076 - INFO - ✅ Completed iteration 13/30 - Total samples: 61
2026-01-23 11:31:01,076 - INFO - 🎯 Best fitness values:
2026-01-23 11:31:01,077 - INFO - 	 Best parameters for best fitness of live_cell_count (sample 39): {'cell_cycle_entry': 1526.73287646256, 'apoptosis_rate': 5.6972530886514257e-05}
2026-01-23 11:31:01,077 - INFO - 	 Fitness: {'live_cell_count': 0.8045753209307664, 'sum_dead_cell_count': 0.1938266989501782}.
2026-01-23 11:31:01,077 - INFO - 	 Best parameters for best fitness of sum_dead_cell_count (sample 4): {'cell_cycle_entry': 1559.1182049626123, 'apoptosis_rate': 5.98522630694583e-05}
2026-01-23 11:31:01,078 - INFO - 	 Fitness: {'live_cell_count': 0.5649144394341963, 'sum_dead_cell_count': 0.8559025559873279}.
2026-01-23 11:31:01,078 - INFO - ============================================================
2026-01-23 11:31:01,078 - INFO - 🔄 Multi-Objective BO Iteration 14/30
2026-01-23 11:31:01,078 - INFO - ============================================================
2026-01-23 11:31:01,078 - INFO - 🔧 Fitting Gaussian Process models...
2026-01-23 11:31:01,128 - INFO - 🎯 Optimizing acquisition function...
2026-01-23 11:31:02,472 - INFO - 📊 Evaluating 1 new candidate(s)...
2026-01-23 11:31:02,472 - INFO - 	 Candidate 1: {'cell_cycle_entry': 1494.9197427548447, 'apoptosis_rate': 6.380004e-05}
2026-01-23 11:35:25,040 - INFO - 	 Results for Sample ID 61: Objectives = {'live_cell_count': np.float64(0.6684846793323015), 'sum_dead_cell_count': np.float64(0.025520192792709607)}, Noise Std = {'live_cell_count': np.float64(0.14610401674178725), 'sum_dead_cell_count': np.float64(0.050775494114411276)}
2026-01-23 11:35:25,048 - INFO - 📊 Iteration 14 Sample(s) [61] : Hypervolume = 0.0003415138631175
2026-01-23 11:35:25,048 - INFO - 🔍 Analyzing convergence...
2026-01-23 11:35:25,049 - WARNING - ⚠️  High noise detected (max 88.0%) - using relaxed convergence criteria
2026-01-23 11:35:25,049 - INFO - 	📋 Convergence Status: in_progress
2026-01-23 11:35:25,050 - INFO - 	💡 Reason: Normal optimization progress
2026-01-23 11:35:25,050 - INFO - 	🎯 Confidence: 40.89%
2026-01-23 11:35:25,050 - INFO - 	📊 Noise level: max=88.0%, avg=68.4%, SNR=1.1
2026-01-23 11:35:25,051 - INFO - ✅ Completed iteration 14/30 - Total samples: 62
2026-01-23 11:35:25,051 - INFO - 🎯 Best fitness values:
2026-01-23 11:35:25,052 - INFO - 	 Best parameters for best fitness of live_cell_count (sample 39): {'cell_cycle_entry': 1526.73287646256, 'apoptosis_rate': 5.6972530886514257e-05}
2026-01-23 11:35:25,052 - INFO - 	 Fitness: {'live_cell_count': 0.8045753209307664, 'sum_dead_cell_count': 0.1938266989501782}.
2026-01-23 11:35:25,052 - INFO - 	 Best parameters for best fitness of sum_dead_cell_count (sample 4): {'cell_cycle_entry': 1559.1182049626123, 'apoptosis_rate': 5.98522630694583e-05}
2026-01-23 11:35:25,052 - INFO - 	 Fitness: {'live_cell_count': 0.5649144394341963, 'sum_dead_cell_count': 0.8559025559873279}.
2026-01-23 11:35:25,052 - INFO - ============================================================
2026-01-23 11:35:25,053 - INFO - 🔄 Multi-Objective BO Iteration 15/30
2026-01-23 11:35:25,053 - INFO - ============================================================
2026-01-23 11:35:25,053 - INFO - 🔧 Fitting Gaussian Process models...
2026-01-23 11:35:25,103 - INFO - 🎯 Optimizing acquisition function...
2026-01-23 11:35:26,424 - INFO - 📊 Evaluating 1 new candidate(s)...
2026-01-23 11:35:26,424 - INFO - 	 Candidate 1: {'cell_cycle_entry': 1146.4310481347356, 'apoptosis_rate': 4.2533360000000006e-05}
2026-01-23 11:40:59,116 - INFO - 	 Results for Sample ID 62: Objectives = {'live_cell_count': np.float64(1.0478164073555139e-18), 'sum_dead_cell_count': np.float64(1.4910710787210043e-05)}, Noise Std = {'live_cell_count': np.float64(2.0777105508180532e-18), 'sum_dead_cell_count': np.float64(2.9757444748696113e-05)}
2026-01-23 11:40:59,121 - INFO - 📊 Iteration 15 Sample(s) [62] : Hypervolume = 0.00036413551864102685
2026-01-23 11:40:59,121 - INFO - 🔍 Analyzing convergence...
2026-01-23 11:40:59,121 - WARNING - ⚠️  High noise detected (max 88.0%) - using relaxed convergence criteria
2026-01-23 11:40:59,122 - INFO - 	📋 Convergence Status: stuck_suboptimal
2026-01-23 11:40:59,122 - INFO - 	💡 Reason: Stuck in suboptimal region: poor exploration or quality despite stagnation
2026-01-23 11:40:59,122 - INFO - 	🎯 Confidence: 42.19%
2026-01-23 11:40:59,122 - INFO - 	📊 Noise level: max=88.0%, avg=68.4%, SNR=1.1
2026-01-23 11:40:59,123 - INFO - 	💡 Suggestion: Poor fitness values: check distance function weights or try different acquisition strategy
2026-01-23 11:40:59,123 - WARNING - 	⚠️  Suboptimal stagnation detected - consider restarting with different settings
2026-01-23 11:40:59,123 - INFO - ✅ Completed iteration 15/30 - Total samples: 63
2026-01-23 11:40:59,123 - INFO - 🎯 Best fitness values:
2026-01-23 11:40:59,123 - INFO - 	 Best parameters for best fitness of live_cell_count (sample 39): {'cell_cycle_entry': 1526.73287646256, 'apoptosis_rate': 5.6972530886514257e-05}
2026-01-23 11:40:59,124 - INFO - 	 Fitness: {'live_cell_count': 0.8045753209307664, 'sum_dead_cell_count': 0.1938266989501782}.
2026-01-23 11:40:59,124 - INFO - 	 Best parameters for best fitness of sum_dead_cell_count (sample 4): {'cell_cycle_entry': 1559.1182049626123, 'apoptosis_rate': 5.98522630694583e-05}
2026-01-23 11:40:59,124 - INFO - 	 Fitness: {'live_cell_count': 0.5649144394341963, 'sum_dead_cell_count': 0.8559025559873279}.
2026-01-23 11:40:59,124 - INFO - ============================================================
2026-01-23 11:40:59,124 - INFO - 🔄 Multi-Objective BO Iteration 16/30
2026-01-23 11:40:59,125 - INFO - ============================================================
2026-01-23 11:40:59,125 - INFO - 🔧 Fitting Gaussian Process models...
2026-01-23 11:40:59,163 - INFO - 🎯 Optimizing acquisition function...
2026-01-23 11:41:00,206 - INFO - 📊 Evaluating 1 new candidate(s)...
2026-01-23 11:41:00,207 - INFO - 	 Candidate 1: {'cell_cycle_entry': 1478.8405380426898, 'apoptosis_rate': 6.380004e-05}
2026-01-23 11:45:24,077 - INFO - 	 Results for Sample ID 63: Objectives = {'live_cell_count': np.float64(0.742936756090595), 'sum_dead_cell_count': np.float64(0.09675640257157585)}, Noise Std = {'live_cell_count': np.float64(0.13138184046814297), 'sum_dead_cell_count': np.float64(0.08094923455841294)}
2026-01-23 11:45:24,083 - INFO - 📊 Iteration 16 Sample(s) [63] : Hypervolume = 0.00035246388000215233
2026-01-23 11:45:24,083 - INFO - 🔍 Analyzing convergence...
2026-01-23 11:45:24,084 - WARNING - ⚠️  High noise detected (max 87.9%) - using relaxed convergence criteria
2026-01-23 11:45:24,085 - INFO - 	📋 Convergence Status: stuck_suboptimal
2026-01-23 11:45:24,085 - INFO - 	💡 Reason: Stuck in suboptimal region: poor exploration or quality despite stagnation
2026-01-23 11:45:24,085 - INFO - 	🎯 Confidence: 34.09%
2026-01-23 11:45:24,085 - INFO - 	📊 Noise level: max=87.9%, avg=67.7%, SNR=1.1
2026-01-23 11:45:24,085 - INFO - 	💡 Suggestion: Poor fitness values: check distance function weights or try different acquisition strategy
2026-01-23 11:45:24,086 - WARNING - 	⚠️  Suboptimal stagnation detected - consider restarting with different settings
2026-01-23 11:45:24,086 - INFO - ✅ Completed iteration 16/30 - Total samples: 64
2026-01-23 11:45:24,086 - INFO - 🎯 Best fitness values:
2026-01-23 11:45:24,087 - INFO - 	 Best parameters for best fitness of live_cell_count (sample 39): {'cell_cycle_entry': 1526.73287646256, 'apoptosis_rate': 5.6972530886514257e-05}
2026-01-23 11:45:24,087 - INFO - 	 Fitness: {'live_cell_count': 0.8045753209307664, 'sum_dead_cell_count': 0.1938266989501782}.
2026-01-23 11:45:24,087 - INFO - 	 Best parameters for best fitness of sum_dead_cell_count (sample 4): {'cell_cycle_entry': 1559.1182049626123, 'apoptosis_rate': 5.98522630694583e-05}
2026-01-23 11:45:24,087 - INFO - 	 Fitness: {'live_cell_count': 0.5649144394341963, 'sum_dead_cell_count': 0.8559025559873279}.
2026-01-23 11:45:24,087 - INFO - ============================================================
2026-01-23 11:45:24,088 - INFO - 🔄 Multi-Objective BO Iteration 17/30
2026-01-23 11:45:24,088 - INFO - ============================================================
2026-01-23 11:45:24,088 - INFO - 🔧 Fitting Gaussian Process models...
2026-01-23 11:45:24,128 - INFO - 🎯 Optimizing acquisition function...
2026-01-23 11:45:26,989 - INFO - 📊 Evaluating 1 new candidate(s)...
2026-01-23 11:45:26,989 - INFO - 	 Candidate 1: {'cell_cycle_entry': 1538.5377348886752, 'apoptosis_rate': 6.380004e-05}
2026-01-23 11:49:56,411 - INFO - 	 Results for Sample ID 64: Objectives = {'live_cell_count': np.float64(0.3759869854829787), 'sum_dead_cell_count': np.float64(0.03254559651751149)}, Noise Std = {'live_cell_count': np.float64(0.20973873309879643), 'sum_dead_cell_count': np.float64(0.04401070198951981)}
2026-01-23 11:49:56,418 - INFO - 📊 Iteration 17 Sample(s) [64] : Hypervolume = 0.00035834516048276937
2026-01-23 11:49:56,418 - INFO - 🔍 Analyzing convergence...
2026-01-23 11:49:56,419 - WARNING - ⚠️  High noise detected (max 88.1%) - using relaxed convergence criteria
2026-01-23 11:49:56,420 - INFO - 	📋 Convergence Status: stuck_suboptimal
2026-01-23 11:49:56,420 - INFO - 	💡 Reason: Stuck in suboptimal region: poor exploration or quality despite stagnation
2026-01-23 11:49:56,420 - INFO - 	🎯 Confidence: 34.27%
2026-01-23 11:49:56,421 - INFO - 	📊 Noise level: max=88.1%, avg=67.9%, SNR=1.1
2026-01-23 11:49:56,421 - INFO - 	💡 Suggestion: Poor fitness values: check distance function weights or try different acquisition strategy
2026-01-23 11:49:56,421 - WARNING - 	⚠️  Suboptimal stagnation detected - consider restarting with different settings
2026-01-23 11:49:56,422 - INFO - ✅ Completed iteration 17/30 - Total samples: 65
2026-01-23 11:49:56,423 - INFO - 🎯 Best fitness values:
2026-01-23 11:49:56,423 - INFO - 	 Best parameters for best fitness of live_cell_count (sample 39): {'cell_cycle_entry': 1526.73287646256, 'apoptosis_rate': 5.6972530886514257e-05}
2026-01-23 11:49:56,423 - INFO - 	 Fitness: {'live_cell_count': 0.8045753209307664, 'sum_dead_cell_count': 0.1938266989501782}.
2026-01-23 11:49:56,424 - INFO - 	 Best parameters for best fitness of sum_dead_cell_count (sample 4): {'cell_cycle_entry': 1559.1182049626123, 'apoptosis_rate': 5.98522630694583e-05}
2026-01-23 11:49:56,424 - INFO - 	 Fitness: {'live_cell_count': 0.5649144394341963, 'sum_dead_cell_count': 0.8559025559873279}.
2026-01-23 11:49:56,424 - INFO - ============================================================
2026-01-23 11:49:56,424 - INFO - 🔄 Multi-Objective BO Iteration 18/30
2026-01-23 11:49:56,425 - INFO - ============================================================
2026-01-23 11:49:56,425 - INFO - 🔧 Fitting Gaussian Process models...
2026-01-23 11:49:56,477 - INFO - 🎯 Optimizing acquisition function...
2026-01-23 11:49:57,964 - INFO - 📊 Evaluating 1 new candidate(s)...
2026-01-23 11:49:57,965 - INFO - 	 Candidate 1: {'cell_cycle_entry': 1502.3114673108414, 'apoptosis_rate': 5.7757494365742485e-05}
2026-01-23 11:54:35,198 - INFO - 	 Results for Sample ID 65: Objectives = {'live_cell_count': np.float64(0.8331083990637896), 'sum_dead_cell_count': np.float64(0.15612294461330625)}, Noise Std = {'live_cell_count': np.float64(0.08419486758400696), 'sum_dead_cell_count': np.float64(0.223200805079449)}
2026-01-23 11:54:35,204 - INFO - 📊 Iteration 18 Sample(s) [65] : Hypervolume = 0.00037838721533225945
2026-01-23 11:54:35,205 - INFO - 🔍 Analyzing convergence...
2026-01-23 11:54:35,205 - WARNING - ⚠️  High noise detected (max 89.3%) - using relaxed convergence criteria
2026-01-23 11:54:35,206 - INFO - 	📋 Convergence Status: stuck_suboptimal
2026-01-23 11:54:35,206 - INFO - 	💡 Reason: Stuck in suboptimal region: poor exploration or quality despite stagnation
2026-01-23 11:54:35,206 - INFO - 	🎯 Confidence: 42.71%
2026-01-23 11:54:35,206 - INFO - 	📊 Noise level: max=89.3%, avg=67.5%, SNR=1.1
2026-01-23 11:54:35,207 - INFO - 	💡 Suggestion: Poor fitness values: check distance function weights or try different acquisition strategy
2026-01-23 11:54:35,207 - WARNING - 	⚠️  Suboptimal stagnation detected - consider restarting with different settings
2026-01-23 11:54:35,207 - INFO - ✅ Completed iteration 18/30 - Total samples: 66
2026-01-23 11:54:35,207 - INFO - 🎯 Best fitness values:
2026-01-23 11:54:35,207 - INFO - 	 Best parameters for best fitness of live_cell_count (sample 65): {'cell_cycle_entry': 1502.3114673108414, 'apoptosis_rate': 5.7757494365742485e-05}
2026-01-23 11:54:35,208 - INFO - 	 Fitness: {'live_cell_count': 0.8331083990637896, 'sum_dead_cell_count': 0.15612294461330625}.
2026-01-23 11:54:35,208 - INFO - 	 Best parameters for best fitness of sum_dead_cell_count (sample 4): {'cell_cycle_entry': 1559.1182049626123, 'apoptosis_rate': 5.98522630694583e-05}
2026-01-23 11:54:35,208 - INFO - 	 Fitness: {'live_cell_count': 0.5649144394341963, 'sum_dead_cell_count': 0.8559025559873279}.
2026-01-23 11:54:35,208 - INFO - ============================================================
2026-01-23 11:54:35,208 - INFO - 🔄 Multi-Objective BO Iteration 19/30
2026-01-23 11:54:35,209 - INFO - ============================================================
2026-01-23 11:54:35,209 - INFO - 🔧 Fitting Gaussian Process models...
2026-01-23 11:54:35,250 - INFO - 🎯 Optimizing acquisition function...
2026-01-23 11:54:38,615 - INFO - 📊 Evaluating 1 new candidate(s)...
2026-01-23 11:54:38,615 - INFO - 	 Candidate 1: {'cell_cycle_entry': 1520.8461164897135, 'apoptosis_rate': 5.037070475122623e-05}
2026-01-23 11:59:10,014 - INFO - 	 Results for Sample ID 66: Objectives = {'live_cell_count': np.float64(0.8080074465483431), 'sum_dead_cell_count': np.float64(0.003255316069501378)}, Noise Std = {'live_cell_count': np.float64(0.13965637339687334), 'sum_dead_cell_count': np.float64(0.006465730156495978)}
2026-01-23 11:59:10,021 - INFO - 📊 Iteration 19 Sample(s) [66] : Hypervolume = 0.0004070249680187205
2026-01-23 11:59:10,021 - INFO - 🔍 Analyzing convergence...
2026-01-23 11:59:10,022 - WARNING - ⚠️  High noise detected (max 89.4%) - using relaxed convergence criteria
2026-01-23 11:59:10,023 - INFO - 	📋 Convergence Status: stuck_suboptimal
2026-01-23 11:59:10,023 - INFO - 	💡 Reason: Stuck in suboptimal region: poor exploration or quality despite stagnation
2026-01-23 11:59:10,023 - INFO - 	🎯 Confidence: 41.98%
2026-01-23 11:59:10,023 - INFO - 	📊 Noise level: max=89.4%, avg=66.9%, SNR=1.1
2026-01-23 11:59:10,024 - INFO - 	💡 Suggestion: Poor fitness values: check distance function weights or try different acquisition strategy
2026-01-23 11:59:10,024 - WARNING - 	⚠️  Suboptimal stagnation detected - consider restarting with different settings
2026-01-23 11:59:10,024 - INFO - ✅ Completed iteration 19/30 - Total samples: 67
2026-01-23 11:59:10,024 - INFO - 🎯 Best fitness values:
2026-01-23 11:59:10,025 - INFO - 	 Best parameters for best fitness of live_cell_count (sample 65): {'cell_cycle_entry': 1502.3114673108414, 'apoptosis_rate': 5.7757494365742485e-05}
2026-01-23 11:59:10,025 - INFO - 	 Fitness: {'live_cell_count': 0.8331083990637896, 'sum_dead_cell_count': 0.15612294461330625}.
2026-01-23 11:59:10,025 - INFO - 	 Best parameters for best fitness of sum_dead_cell_count (sample 4): {'cell_cycle_entry': 1559.1182049626123, 'apoptosis_rate': 5.98522630694583e-05}
2026-01-23 11:59:10,025 - INFO - 	 Fitness: {'live_cell_count': 0.5649144394341963, 'sum_dead_cell_count': 0.8559025559873279}.
2026-01-23 11:59:10,025 - INFO - ============================================================
2026-01-23 11:59:10,025 - INFO - 🔄 Multi-Objective BO Iteration 20/30
2026-01-23 11:59:10,026 - INFO - ============================================================
2026-01-23 11:59:10,026 - INFO - 🔧 Fitting Gaussian Process models...
2026-01-23 11:59:10,070 - INFO - 🎯 Optimizing acquisition function...
2026-01-23 11:59:11,597 - INFO - 📊 Evaluating 1 new candidate(s)...
2026-01-23 11:59:11,597 - INFO - 	 Candidate 1: {'cell_cycle_entry': 1491.7350835521092, 'apoptosis_rate': 6.063969176097474e-05}
2026-01-23 12:03:35,137 - INFO - 	 Results for Sample ID 67: Objectives = {'live_cell_count': np.float64(0.8604650028634341), 'sum_dead_cell_count': np.float64(0.17346377711885388)}, Noise Std = {'live_cell_count': np.float64(0.12113162957542457), 'sum_dead_cell_count': np.float64(0.2524328664752449)}
2026-01-23 12:03:35,145 - INFO - 📊 Iteration 20 Sample(s) [67] : Hypervolume = 0.0004130205181744017
2026-01-23 12:03:35,145 - INFO - 🔍 Analyzing convergence...
2026-01-23 12:03:35,146 - WARNING - ⚠️  High noise detected (max 90.7%) - using relaxed convergence criteria
2026-01-23 12:03:35,147 - INFO - 	📋 Convergence Status: stuck_suboptimal
2026-01-23 12:03:35,147 - INFO - 	💡 Reason: Stuck in suboptimal region: poor exploration or quality despite stagnation
2026-01-23 12:03:35,147 - INFO - 	🎯 Confidence: 43.67%
2026-01-23 12:03:35,148 - INFO - 	📊 Noise level: max=90.7%, avg=66.9%, SNR=1.1
2026-01-23 12:03:35,148 - INFO - 	💡 Suggestion: Poor fitness values: check distance function weights or try different acquisition strategy
2026-01-23 12:03:35,148 - WARNING - 	⚠️  Suboptimal stagnation detected - consider restarting with different settings
2026-01-23 12:03:35,149 - INFO - ✅ Completed iteration 20/30 - Total samples: 68
2026-01-23 12:03:35,149 - INFO - 🎯 Best fitness values:
2026-01-23 12:03:35,150 - INFO - 	 Best parameters for best fitness of live_cell_count (sample 67): {'cell_cycle_entry': 1491.7350835521092, 'apoptosis_rate': 6.063969176097474e-05}
2026-01-23 12:03:35,150 - INFO - 	 Fitness: {'live_cell_count': 0.8604650028634341, 'sum_dead_cell_count': 0.17346377711885388}.
2026-01-23 12:03:35,150 - INFO - 	 Best parameters for best fitness of sum_dead_cell_count (sample 4): {'cell_cycle_entry': 1559.1182049626123, 'apoptosis_rate': 5.98522630694583e-05}
2026-01-23 12:03:35,151 - INFO - 	 Fitness: {'live_cell_count': 0.5649144394341963, 'sum_dead_cell_count': 0.8559025559873279}.
2026-01-23 12:03:35,151 - INFO - ============================================================
2026-01-23 12:03:35,151 - INFO - 🔄 Multi-Objective BO Iteration 21/30
2026-01-23 12:03:35,151 - INFO - ============================================================
2026-01-23 12:03:35,152 - INFO - 🔧 Fitting Gaussian Process models...
2026-01-23 12:03:35,196 - INFO - 🎯 Optimizing acquisition function...
2026-01-23 12:03:36,382 - INFO - 📊 Evaluating 1 new candidate(s)...
2026-01-23 12:03:36,383 - INFO - 	 Candidate 1: {'cell_cycle_entry': 1645.154328096521, 'apoptosis_rate': 4.2533360000000006e-05}
2026-01-23 12:07:49,213 - INFO - 	 Results for Sample ID 68: Objectives = {'live_cell_count': np.float64(0.3008557522476735), 'sum_dead_cell_count': np.float64(1.0235341287729807e-25)}, Noise Std = {'live_cell_count': np.float64(0.14403128375874152), 'sum_dead_cell_count': np.float64(2.0470682574368614e-25)}
2026-01-23 12:07:49,221 - INFO - 📊 Iteration 21 Sample(s) [68] : Hypervolume = 0.0004213151004276176
2026-01-23 12:07:49,221 - INFO - 🔍 Analyzing convergence...
2026-01-23 12:07:49,222 - WARNING - ⚠️  High noise detected (max 90.7%) - using relaxed convergence criteria
2026-01-23 12:07:49,223 - INFO - 	📋 Convergence Status: stuck_suboptimal
2026-01-23 12:07:49,223 - INFO - 	💡 Reason: Stuck in suboptimal region: poor exploration or quality despite stagnation
2026-01-23 12:07:49,223 - INFO - 	🎯 Confidence: 43.38%
2026-01-23 12:07:49,223 - INFO - 	📊 Noise level: max=90.7%, avg=66.9%, SNR=1.1
2026-01-23 12:07:49,224 - INFO - 	💡 Suggestion: Poor fitness values: check distance function weights or try different acquisition strategy
2026-01-23 12:07:49,224 - WARNING - 	⚠️  Suboptimal stagnation detected - consider restarting with different settings
2026-01-23 12:07:49,224 - INFO - ✅ Completed iteration 21/30 - Total samples: 69
2026-01-23 12:07:49,225 - INFO - 🎯 Best fitness values:
2026-01-23 12:07:49,225 - INFO - 	 Best parameters for best fitness of live_cell_count (sample 67): {'cell_cycle_entry': 1491.7350835521092, 'apoptosis_rate': 6.063969176097474e-05}
2026-01-23 12:07:49,225 - INFO - 	 Fitness: {'live_cell_count': 0.8604650028634341, 'sum_dead_cell_count': 0.17346377711885388}.
2026-01-23 12:07:49,226 - INFO - 	 Best parameters for best fitness of sum_dead_cell_count (sample 4): {'cell_cycle_entry': 1559.1182049626123, 'apoptosis_rate': 5.98522630694583e-05}
2026-01-23 12:07:49,226 - INFO - 	 Fitness: {'live_cell_count': 0.5649144394341963, 'sum_dead_cell_count': 0.8559025559873279}.
2026-01-23 12:07:49,226 - INFO - ============================================================
2026-01-23 12:07:49,226 - INFO - 🔄 Multi-Objective BO Iteration 22/30
2026-01-23 12:07:49,226 - INFO - ============================================================
2026-01-23 12:07:49,226 - INFO - 🔧 Fitting Gaussian Process models...
2026-01-23 12:07:49,268 - INFO - 🎯 Optimizing acquisition function...
2026-01-23 12:07:49,942 - INFO - 📊 Evaluating 1 new candidate(s)...
2026-01-23 12:07:49,943 - INFO - 	 Candidate 1: {'cell_cycle_entry': 1111.111112, 'apoptosis_rate': 6.380004e-05}
2026-01-23 12:13:24,936 - INFO - 	 Results for Sample ID 69: Objectives = {'live_cell_count': np.float64(4.9000613240716156e-15), 'sum_dead_cell_count': np.float64(6.143347061036789e-14)}, Noise Std = {'live_cell_count': np.float64(9.781084309377223e-15), 'sum_dead_cell_count': np.float64(1.2286694122073578e-13)}
2026-01-23 12:13:24,943 - INFO - 📊 Iteration 22 Sample(s) [69] : Hypervolume = 0.00042354597386963023
2026-01-23 12:13:24,943 - INFO - 🔍 Analyzing convergence...
2026-01-23 12:13:24,944 - WARNING - ⚠️  High noise detected (max 90.7%) - using relaxed convergence criteria
2026-01-23 12:13:24,944 - INFO - 	📋 Convergence Status: stuck_suboptimal
2026-01-23 12:13:24,945 - INFO - 	💡 Reason: Stuck in suboptimal region: poor exploration or quality despite stagnation
2026-01-23 12:13:24,945 - INFO - 	🎯 Confidence: 40.39%
2026-01-23 12:13:24,945 - INFO - 	📊 Noise level: max=90.7%, avg=66.9%, SNR=1.1
2026-01-23 12:13:24,945 - INFO - 	💡 Suggestion: Poor fitness values: check distance function weights or try different acquisition strategy
2026-01-23 12:13:24,945 - WARNING - 	⚠️  Suboptimal stagnation detected - consider restarting with different settings
2026-01-23 12:13:24,945 - INFO - ✅ Completed iteration 22/30 - Total samples: 70
2026-01-23 12:13:24,946 - INFO - 🎯 Best fitness values:
2026-01-23 12:13:24,946 - INFO - 	 Best parameters for best fitness of live_cell_count (sample 67): {'cell_cycle_entry': 1491.7350835521092, 'apoptosis_rate': 6.063969176097474e-05}
2026-01-23 12:13:24,946 - INFO - 	 Fitness: {'live_cell_count': 0.8604650028634341, 'sum_dead_cell_count': 0.17346377711885388}.
2026-01-23 12:13:24,946 - INFO - 	 Best parameters for best fitness of sum_dead_cell_count (sample 4): {'cell_cycle_entry': 1559.1182049626123, 'apoptosis_rate': 5.98522630694583e-05}
2026-01-23 12:13:24,947 - INFO - 	 Fitness: {'live_cell_count': 0.5649144394341963, 'sum_dead_cell_count': 0.8559025559873279}.
2026-01-23 12:13:24,947 - INFO - ============================================================
2026-01-23 12:13:24,947 - INFO - 🔄 Multi-Objective BO Iteration 23/30
2026-01-23 12:13:24,947 - INFO - ============================================================
2026-01-23 12:13:24,947 - INFO - 🔧 Fitting Gaussian Process models...
2026-01-23 12:13:25,040 - INFO - 🎯 Optimizing acquisition function...
2026-01-23 12:13:26,600 - INFO - 📊 Evaluating 1 new candidate(s)...
2026-01-23 12:13:26,600 - INFO - 	 Candidate 1: {'cell_cycle_entry': 1411.3816005442063, 'apoptosis_rate': 6.380004e-05}
2026-01-23 12:18:30,097 - INFO - 	 Results for Sample ID 70: Objectives = {'live_cell_count': np.float64(0.3890155498569935), 'sum_dead_cell_count': np.float64(1.7322168837076787e-05)}, Noise Std = {'live_cell_count': np.float64(0.23975900207883163), 'sum_dead_cell_count': np.float64(2.1199388495337684e-05)}
2026-01-23 12:18:30,104 - INFO - 📊 Iteration 23 Sample(s) [70] : Hypervolume = 0.0004210626937628375
2026-01-23 12:18:30,104 - INFO - 🔍 Analyzing convergence...
2026-01-23 12:18:30,105 - WARNING - ⚠️  High noise detected (max 90.7%) - using relaxed convergence criteria
2026-01-23 12:18:30,106 - INFO - 	📋 Convergence Status: stuck_suboptimal
2026-01-23 12:18:30,106 - INFO - 	💡 Reason: Stuck in suboptimal region: poor exploration or quality despite stagnation
2026-01-23 12:18:30,106 - INFO - 	🎯 Confidence: 40.43%
2026-01-23 12:18:30,106 - INFO - 	📊 Noise level: max=90.7%, avg=67.1%, SNR=1.1
2026-01-23 12:18:30,107 - INFO - 	💡 Suggestion: Poor fitness values: check distance function weights or try different acquisition strategy
2026-01-23 12:18:30,107 - WARNING - 	⚠️  Suboptimal stagnation detected - consider restarting with different settings
2026-01-23 12:18:30,107 - INFO - ✅ Completed iteration 23/30 - Total samples: 71
2026-01-23 12:18:30,108 - INFO - 🎯 Best fitness values:
2026-01-23 12:18:30,108 - INFO - 	 Best parameters for best fitness of live_cell_count (sample 67): {'cell_cycle_entry': 1491.7350835521092, 'apoptosis_rate': 6.063969176097474e-05}
2026-01-23 12:18:30,108 - INFO - 	 Fitness: {'live_cell_count': 0.8604650028634341, 'sum_dead_cell_count': 0.17346377711885388}.
2026-01-23 12:18:30,108 - INFO - 	 Best parameters for best fitness of sum_dead_cell_count (sample 4): {'cell_cycle_entry': 1559.1182049626123, 'apoptosis_rate': 5.98522630694583e-05}
2026-01-23 12:18:30,109 - INFO - 	 Fitness: {'live_cell_count': 0.5649144394341963, 'sum_dead_cell_count': 0.8559025559873279}.
2026-01-23 12:18:30,109 - INFO - ============================================================
2026-01-23 12:18:30,109 - INFO - 🔄 Multi-Objective BO Iteration 24/30
2026-01-23 12:18:30,109 - INFO - ============================================================
2026-01-23 12:18:30,109 - INFO - 🔧 Fitting Gaussian Process models...
2026-01-23 12:18:30,154 - INFO - 🎯 Optimizing acquisition function...
2026-01-23 12:18:31,691 - INFO - 📊 Evaluating 1 new candidate(s)...
2026-01-23 12:18:31,692 - INFO - 	 Candidate 1: {'cell_cycle_entry': 1507.4979964286235, 'apoptosis_rate': 4.2533360000000006e-05}
2026-01-23 12:23:23,894 - INFO - 	 Results for Sample ID 71: Objectives = {'live_cell_count': np.float64(0.5837630877629089), 'sum_dead_cell_count': np.float64(3.872110607430501e-27)}, Noise Std = {'live_cell_count': np.float64(0.17974188692238202), 'sum_dead_cell_count': np.float64(3.266012632616336e-27)}
2026-01-23 12:23:23,900 - INFO - 📊 Iteration 24 Sample(s) [71] : Hypervolume = 0.0003807216727742176
2026-01-23 12:23:23,901 - INFO - 🔍 Analyzing convergence...
2026-01-23 12:23:23,901 - WARNING - ⚠️  High noise detected (max 90.7%) - using relaxed convergence criteria
2026-01-23 12:23:23,902 - INFO - 	📋 Convergence Status: stuck_suboptimal
2026-01-23 12:23:23,902 - INFO - 	💡 Reason: Stuck in suboptimal region: poor exploration or quality despite stagnation
2026-01-23 12:23:23,902 - INFO - 	🎯 Confidence: 44.99%
2026-01-23 12:23:23,902 - INFO - 	📊 Noise level: max=90.7%, avg=66.9%, SNR=1.1
2026-01-23 12:23:23,902 - INFO - 	💡 Suggestion: Poor fitness values: check distance function weights or try different acquisition strategy
2026-01-23 12:23:23,903 - WARNING - 	⚠️  Suboptimal stagnation detected - consider restarting with different settings
2026-01-23 12:23:23,903 - INFO - ✅ Completed iteration 24/30 - Total samples: 72
2026-01-23 12:23:23,903 - INFO - 🎯 Best fitness values:
2026-01-23 12:23:23,903 - INFO - 	 Best parameters for best fitness of live_cell_count (sample 67): {'cell_cycle_entry': 1491.7350835521092, 'apoptosis_rate': 6.063969176097474e-05}
2026-01-23 12:23:23,904 - INFO - 	 Fitness: {'live_cell_count': 0.8604650028634341, 'sum_dead_cell_count': 0.17346377711885388}.
2026-01-23 12:23:23,904 - INFO - 	 Best parameters for best fitness of sum_dead_cell_count (sample 4): {'cell_cycle_entry': 1559.1182049626123, 'apoptosis_rate': 5.98522630694583e-05}
2026-01-23 12:23:23,904 - INFO - 	 Fitness: {'live_cell_count': 0.5649144394341963, 'sum_dead_cell_count': 0.8559025559873279}.
2026-01-23 12:23:23,904 - INFO - ============================================================
2026-01-23 12:23:23,904 - INFO - 🔄 Multi-Objective BO Iteration 25/30
2026-01-23 12:23:23,905 - INFO - ============================================================
2026-01-23 12:23:23,905 - INFO - 🔧 Fitting Gaussian Process models...
2026-01-23 12:23:23,948 - INFO - 🎯 Optimizing acquisition function...
2026-01-23 12:23:25,531 - INFO - 📊 Evaluating 1 new candidate(s)...
2026-01-23 12:23:25,532 - INFO - 	 Candidate 1: {'cell_cycle_entry': 1166.314316925292, 'apoptosis_rate': 6.380004e-05}
2026-01-23 12:28:34,894 - INFO - 	 Results for Sample ID 72: Objectives = {'live_cell_count': np.float64(2.2950860055579468e-11), 'sum_dead_cell_count': np.float64(3.56326211810554e-25)}, Noise Std = {'live_cell_count': np.float64(2.7994616673686807e-11), 'sum_dead_cell_count': np.float64(4.363850910309665e-25)}
2026-01-23 12:28:34,901 - INFO - 📊 Iteration 25 Sample(s) [72] : Hypervolume = 0.0003826921051833887
2026-01-23 12:28:34,902 - INFO - 🔍 Analyzing convergence...
2026-01-23 12:28:34,902 - WARNING - ⚠️  High noise detected (max 90.7%) - using relaxed convergence criteria
2026-01-23 12:28:34,903 - INFO - 	📋 Convergence Status: stuck_suboptimal
2026-01-23 12:28:34,903 - INFO - 	💡 Reason: Stuck in suboptimal region: poor exploration or quality despite stagnation
2026-01-23 12:28:34,903 - INFO - 	🎯 Confidence: 42.87%
2026-01-23 12:28:34,904 - INFO - 	📊 Noise level: max=90.7%, avg=66.9%, SNR=1.1
2026-01-23 12:28:34,904 - INFO - 	💡 Suggestion: Poor fitness values: check distance function weights or try different acquisition strategy
2026-01-23 12:28:34,904 - WARNING - 	⚠️  Suboptimal stagnation detected - consider restarting with different settings
2026-01-23 12:28:34,904 - INFO - ✅ Completed iteration 25/30 - Total samples: 73
2026-01-23 12:28:34,904 - INFO - 🎯 Best fitness values:
2026-01-23 12:28:34,905 - INFO - 	 Best parameters for best fitness of live_cell_count (sample 67): {'cell_cycle_entry': 1491.7350835521092, 'apoptosis_rate': 6.063969176097474e-05}
2026-01-23 12:28:34,905 - INFO - 	 Fitness: {'live_cell_count': 0.8604650028634341, 'sum_dead_cell_count': 0.17346377711885388}.
2026-01-23 12:28:34,905 - INFO - 	 Best parameters for best fitness of sum_dead_cell_count (sample 4): {'cell_cycle_entry': 1559.1182049626123, 'apoptosis_rate': 5.98522630694583e-05}
2026-01-23 12:28:34,905 - INFO - 	 Fitness: {'live_cell_count': 0.5649144394341963, 'sum_dead_cell_count': 0.8559025559873279}.
2026-01-23 12:28:34,905 - INFO - ============================================================
2026-01-23 12:28:34,906 - INFO - 🔄 Multi-Objective BO Iteration 26/30
2026-01-23 12:28:34,906 - INFO - ============================================================
2026-01-23 12:28:34,906 - INFO - 🔧 Fitting Gaussian Process models...
2026-01-23 12:28:34,946 - INFO - 🎯 Optimizing acquisition function...
2026-01-23 12:28:36,356 - INFO - 📊 Evaluating 1 new candidate(s)...
2026-01-23 12:28:36,356 - INFO - 	 Candidate 1: {'cell_cycle_entry': 1666.6666679999998, 'apoptosis_rate': 5.6451168300606e-05}
2026-01-23 12:32:22,566 - INFO - 	 Results for Sample ID 73: Objectives = {'live_cell_count': np.float64(0.0005234388152754113), 'sum_dead_cell_count': np.float64(0.0017009567394043299)}, Noise Std = {'live_cell_count': np.float64(0.00045896277299482634), 'sum_dead_cell_count': np.float64(0.0033638380254406627)}
2026-01-23 12:32:22,572 - INFO - 📊 Iteration 26 Sample(s) [73] : Hypervolume = 0.00037741608298349935
2026-01-23 12:32:22,572 - INFO - 🔍 Analyzing convergence...
2026-01-23 12:32:22,573 - WARNING - ⚠️  High noise detected (max 90.7%) - using relaxed convergence criteria
2026-01-23 12:32:22,573 - INFO - 	📋 Convergence Status: stuck_suboptimal
2026-01-23 12:32:22,573 - INFO - 	💡 Reason: Stuck in suboptimal region: poor exploration or quality despite stagnation
2026-01-23 12:32:22,574 - INFO - 	🎯 Confidence: 33.37%
2026-01-23 12:32:22,574 - INFO - 	📊 Noise level: max=90.7%, avg=66.9%, SNR=1.1
2026-01-23 12:32:22,574 - INFO - 	💡 Suggestion: Poor fitness values: check distance function weights or try different acquisition strategy
2026-01-23 12:32:22,574 - WARNING - 	⚠️  Suboptimal stagnation detected - consider restarting with different settings
2026-01-23 12:32:22,574 - INFO - ✅ Completed iteration 26/30 - Total samples: 74
2026-01-23 12:32:22,575 - INFO - 🎯 Best fitness values:
2026-01-23 12:32:22,575 - INFO - 	 Best parameters for best fitness of live_cell_count (sample 67): {'cell_cycle_entry': 1491.7350835521092, 'apoptosis_rate': 6.063969176097474e-05}
2026-01-23 12:32:22,575 - INFO - 	 Fitness: {'live_cell_count': 0.8604650028634341, 'sum_dead_cell_count': 0.17346377711885388}.
2026-01-23 12:32:22,575 - INFO - 	 Best parameters for best fitness of sum_dead_cell_count (sample 4): {'cell_cycle_entry': 1559.1182049626123, 'apoptosis_rate': 5.98522630694583e-05}
2026-01-23 12:32:22,575 - INFO - 	 Fitness: {'live_cell_count': 0.5649144394341963, 'sum_dead_cell_count': 0.8559025559873279}.
2026-01-23 12:32:22,575 - INFO - ============================================================
2026-01-23 12:32:22,576 - INFO - 🔄 Multi-Objective BO Iteration 27/30
2026-01-23 12:32:22,576 - INFO - ============================================================
2026-01-23 12:32:22,576 - INFO - 🔧 Fitting Gaussian Process models...
2026-01-23 12:32:22,616 - INFO - 🎯 Optimizing acquisition function...
2026-01-23 12:32:23,889 - INFO - 📊 Evaluating 1 new candidate(s)...
2026-01-23 12:32:23,889 - INFO - 	 Candidate 1: {'cell_cycle_entry': 1452.0487778317263, 'apoptosis_rate': 4.2533360000000006e-05}
2026-01-23 12:36:50,854 - INFO - 	 Results for Sample ID 74: Objectives = {'live_cell_count': np.float64(0.04679203425056402), 'sum_dead_cell_count': np.float64(5.9855636059079595e-21)}, Noise Std = {'live_cell_count': np.float64(0.035706405336793715), 'sum_dead_cell_count': np.float64(1.1971102438835434e-20)}
2026-01-23 12:36:50,859 - INFO - 📊 Iteration 27 Sample(s) [74] : Hypervolume = 0.0003915254036404926
2026-01-23 12:36:50,859 - INFO - 🔍 Analyzing convergence...
2026-01-23 12:36:50,859 - WARNING - ⚠️  High noise detected (max 90.7%) - using relaxed convergence criteria
2026-01-23 12:36:50,860 - INFO - 	📋 Convergence Status: stuck_suboptimal
2026-01-23 12:36:50,860 - INFO - 	💡 Reason: Stuck in suboptimal region: poor exploration or quality despite stagnation
2026-01-23 12:36:50,860 - INFO - 	🎯 Confidence: 44.10%
2026-01-23 12:36:50,860 - INFO - 	📊 Noise level: max=90.7%, avg=67.0%, SNR=1.1
2026-01-23 12:36:50,861 - INFO - 	💡 Suggestion: Poor fitness values: check distance function weights or try different acquisition strategy
2026-01-23 12:36:50,861 - WARNING - 	⚠️  Suboptimal stagnation detected - consider restarting with different settings
2026-01-23 12:36:50,861 - INFO - ✅ Completed iteration 27/30 - Total samples: 75
2026-01-23 12:36:50,861 - INFO - 🎯 Best fitness values:
2026-01-23 12:36:50,861 - INFO - 	 Best parameters for best fitness of live_cell_count (sample 67): {'cell_cycle_entry': 1491.7350835521092, 'apoptosis_rate': 6.063969176097474e-05}
2026-01-23 12:36:50,861 - INFO - 	 Fitness: {'live_cell_count': 0.8604650028634341, 'sum_dead_cell_count': 0.17346377711885388}.
2026-01-23 12:36:50,862 - INFO - 	 Best parameters for best fitness of sum_dead_cell_count (sample 4): {'cell_cycle_entry': 1559.1182049626123, 'apoptosis_rate': 5.98522630694583e-05}
2026-01-23 12:36:50,862 - INFO - 	 Fitness: {'live_cell_count': 0.5649144394341963, 'sum_dead_cell_count': 0.8559025559873279}.
2026-01-23 12:36:50,862 - INFO - ============================================================
2026-01-23 12:36:50,862 - INFO - 🔄 Multi-Objective BO Iteration 28/30
2026-01-23 12:36:50,863 - INFO - ============================================================
2026-01-23 12:36:50,863 - INFO - 🔧 Fitting Gaussian Process models...
2026-01-23 12:36:50,901 - INFO - 🎯 Optimizing acquisition function...
2026-01-23 12:36:52,159 - INFO - 📊 Evaluating 1 new candidate(s)...
2026-01-23 12:36:52,159 - INFO - 	 Candidate 1: {'cell_cycle_entry': 1608.9419570257448, 'apoptosis_rate': 4.2533360000000006e-05}
2026-01-23 12:40:57,875 - INFO - 	 Results for Sample ID 75: Objectives = {'live_cell_count': np.float64(0.3759662487879447), 'sum_dead_cell_count': np.float64(3.163286774258182e-26)}, Noise Std = {'live_cell_count': np.float64(0.13585069682271253), 'sum_dead_cell_count': np.float64(3.8742192535099356e-26)}
2026-01-23 12:40:57,880 - INFO - 📊 Iteration 28 Sample(s) [75] : Hypervolume = 0.000388297700028246
2026-01-23 12:40:57,881 - INFO - 🔍 Analyzing convergence...
2026-01-23 12:40:57,881 - WARNING - ⚠️  High noise detected (max 90.7%) - using relaxed convergence criteria
2026-01-23 12:40:57,882 - INFO - 	📋 Convergence Status: stuck_suboptimal
2026-01-23 12:40:57,882 - INFO - 	💡 Reason: Stuck in suboptimal region: poor exploration or quality despite stagnation
2026-01-23 12:40:57,882 - INFO - 	🎯 Confidence: 44.32%
2026-01-23 12:40:57,882 - INFO - 	📊 Noise level: max=90.7%, avg=66.9%, SNR=1.1
2026-01-23 12:40:57,883 - INFO - 	💡 Suggestion: Poor fitness values: check distance function weights or try different acquisition strategy
2026-01-23 12:40:57,883 - WARNING - 	⚠️  Suboptimal stagnation detected - consider restarting with different settings
2026-01-23 12:40:57,883 - INFO - ✅ Completed iteration 28/30 - Total samples: 76
2026-01-23 12:40:57,883 - INFO - 🎯 Best fitness values:
2026-01-23 12:40:57,883 - INFO - 	 Best parameters for best fitness of live_cell_count (sample 67): {'cell_cycle_entry': 1491.7350835521092, 'apoptosis_rate': 6.063969176097474e-05}
2026-01-23 12:40:57,884 - INFO - 	 Fitness: {'live_cell_count': 0.8604650028634341, 'sum_dead_cell_count': 0.17346377711885388}.
2026-01-23 12:40:57,884 - INFO - 	 Best parameters for best fitness of sum_dead_cell_count (sample 4): {'cell_cycle_entry': 1559.1182049626123, 'apoptosis_rate': 5.98522630694583e-05}
2026-01-23 12:40:57,884 - INFO - 	 Fitness: {'live_cell_count': 0.5649144394341963, 'sum_dead_cell_count': 0.8559025559873279}.
2026-01-23 12:40:57,884 - INFO - ============================================================
2026-01-23 12:40:57,884 - INFO - 🔄 Multi-Objective BO Iteration 29/30
2026-01-23 12:40:57,885 - INFO - ============================================================
2026-01-23 12:40:57,885 - INFO - 🔧 Fitting Gaussian Process models...
2026-01-23 12:40:57,924 - INFO - 🎯 Optimizing acquisition function...
2026-01-23 12:40:59,558 - INFO - 📊 Evaluating 1 new candidate(s)...
2026-01-23 12:40:59,558 - INFO - 	 Candidate 1: {'cell_cycle_entry': 1560.7994933219165, 'apoptosis_rate': 4.2533360000000006e-05}
2026-01-23 12:45:08,352 - INFO - 	 Results for Sample ID 76: Objectives = {'live_cell_count': np.float64(0.7325283829940328), 'sum_dead_cell_count': np.float64(8.232696682258146e-37)}, Noise Std = {'live_cell_count': np.float64(0.2885063498354789), 'sum_dead_cell_count': np.float64(1.6465036943779402e-36)}
2026-01-23 12:45:08,358 - INFO - 📊 Iteration 29 Sample(s) [76] : Hypervolume = 0.0003963879542438786
2026-01-23 12:45:08,358 - INFO - 🔍 Analyzing convergence...
2026-01-23 12:45:08,359 - WARNING - ⚠️  High noise detected (max 90.7%) - using relaxed convergence criteria
2026-01-23 12:45:08,360 - INFO - 	📋 Convergence Status: stuck_suboptimal
2026-01-23 12:45:08,360 - INFO - 	💡 Reason: Stuck in suboptimal region: poor exploration or quality despite stagnation
2026-01-23 12:45:08,360 - INFO - 	🎯 Confidence: 42.97%
2026-01-23 12:45:08,360 - INFO - 	📊 Noise level: max=90.7%, avg=66.8%, SNR=1.1
2026-01-23 12:45:08,360 - INFO - 	💡 Suggestion: Poor fitness values: check distance function weights or try different acquisition strategy
2026-01-23 12:45:08,361 - WARNING - 	⚠️  Suboptimal stagnation detected - consider restarting with different settings
2026-01-23 12:45:08,361 - INFO - ✅ Completed iteration 29/30 - Total samples: 77
2026-01-23 12:45:08,361 - INFO - 🎯 Best fitness values:
2026-01-23 12:45:08,361 - INFO - 	 Best parameters for best fitness of live_cell_count (sample 67): {'cell_cycle_entry': 1491.7350835521092, 'apoptosis_rate': 6.063969176097474e-05}
2026-01-23 12:45:08,362 - INFO - 	 Fitness: {'live_cell_count': 0.8604650028634341, 'sum_dead_cell_count': 0.17346377711885388}.
2026-01-23 12:45:08,362 - INFO - 	 Best parameters for best fitness of sum_dead_cell_count (sample 4): {'cell_cycle_entry': 1559.1182049626123, 'apoptosis_rate': 5.98522630694583e-05}
2026-01-23 12:45:08,362 - INFO - 	 Fitness: {'live_cell_count': 0.5649144394341963, 'sum_dead_cell_count': 0.8559025559873279}.
2026-01-23 12:45:08,362 - INFO - ============================================================
2026-01-23 12:45:08,362 - INFO - 🔄 Multi-Objective BO Iteration 30/30
2026-01-23 12:45:08,362 - INFO - ============================================================
2026-01-23 12:45:08,363 - INFO - 🔧 Fitting Gaussian Process models...
2026-01-23 12:45:08,403 - INFO - 🎯 Optimizing acquisition function...
2026-01-23 12:45:09,842 - INFO - 📊 Evaluating 1 new candidate(s)...
2026-01-23 12:45:09,842 - INFO - 	 Candidate 1: {'cell_cycle_entry': 1519.492123331544, 'apoptosis_rate': 6.380004e-05}
2026-01-23 12:49:21,964 - INFO - 	 Results for Sample ID 77: Objectives = {'live_cell_count': np.float64(0.5123355315456687), 'sum_dead_cell_count': np.float64(0.00960433753072404)}, Noise Std = {'live_cell_count': np.float64(0.35227237793330834), 'sum_dead_cell_count': np.float64(0.01172693165433806)}
2026-01-23 12:49:21,970 - INFO - 📊 Iteration 30 Sample(s) [77] : Hypervolume = 0.0003894153117067585
2026-01-23 12:49:21,971 - INFO - 🔍 Analyzing convergence...
2026-01-23 12:49:21,971 - WARNING - ⚠️  High noise detected (max 90.7%) - using relaxed convergence criteria
2026-01-23 12:49:21,972 - INFO - 	📋 Convergence Status: stuck_suboptimal
2026-01-23 12:49:21,972 - INFO - 	💡 Reason: Stuck in suboptimal region: poor exploration or quality despite stagnation
2026-01-23 12:49:21,972 - INFO - 	🎯 Confidence: 42.34%
2026-01-23 12:49:21,972 - INFO - 	📊 Noise level: max=90.7%, avg=67.2%, SNR=1.1
2026-01-23 12:49:21,973 - INFO - 	💡 Suggestion: Poor fitness values: check distance function weights or try different acquisition strategy
2026-01-23 12:49:21,973 - WARNING - 	⚠️  Suboptimal stagnation detected - consider restarting with different settings
2026-01-23 12:49:21,973 - INFO - ✅ Completed iteration 30/30 - Total samples: 78
2026-01-23 12:49:21,973 - INFO - 🎯 Best fitness values:
2026-01-23 12:49:21,973 - INFO - 	 Best parameters for best fitness of live_cell_count (sample 67): {'cell_cycle_entry': 1491.7350835521092, 'apoptosis_rate': 6.063969176097474e-05}
2026-01-23 12:49:21,974 - INFO - 	 Fitness: {'live_cell_count': 0.8604650028634341, 'sum_dead_cell_count': 0.17346377711885388}.
2026-01-23 12:49:21,974 - INFO - 	 Best parameters for best fitness of sum_dead_cell_count (sample 4): {'cell_cycle_entry': 1559.1182049626123, 'apoptosis_rate': 5.98522630694583e-05}
2026-01-23 12:49:21,974 - INFO - 	 Fitness: {'live_cell_count': 0.5649144394341963, 'sum_dead_cell_count': 0.8559025559873279}.
2026-01-23 12:49:21,974 - INFO - ✅ Multi-objective Bayesian optimization completed successfully!

Pareto front analysis

from uq_physicell.bo import load_structure, analyze_pareto_results, plot_parameter_space, get_observed_qoi
# Load the database and perform analysis
df_metadata, df_param_space, df_qois, df_gp_models, df_samples, df_output = load_structure(db_path)
# Comprehensive Pareto analysis
pareto_data = analyze_pareto_results(df_qois, df_samples, df_output)
# Plot with pareto front points
pareto_points = {f"Pareto Point {i}": param for i, param in enumerate(pareto_data['pareto_front']['parameters'])}
plot_parameter_space(df_samples, df_param_space, params=pareto_points, real_value=dic_real_value)
df_obs_qoi = get_observed_qoi(df_metadata['ObsData_Path'].values[0], df_qois)
============================================================
🔍 COMPREHENSIVE PARETO ANALYSIS
============================================================

📊 Extracting all Pareto points ...
🎯 Current Pareto front size: 5

🎯 CURRENT PARETO FRONT:
   Number of Pareto optimal points: 5
   Sample IDs: [4, 13, 16, 39, 67]

   📋 Pareto Front Details:
   Point 1 (Sample 4):
      Fitness: {'live_cell_count': np.float64(0.5649144394341963), 'sum_dead_cell_count': np.float64(0.8559025559873279)}
      Parameters: {'apoptosis_rate': 5.98522630694583e-05, 'cell_cycle_entry': 1559.1182049626123}
   Point 2 (Sample 13):
      Fitness: {'live_cell_count': np.float64(0.7012471264348298), 'sum_dead_cell_count': np.float64(0.6433052738103898)}
      Parameters: {'apoptosis_rate': 5.763103537976935e-05, 'cell_cycle_entry': 1461.3241750226885}
   Point 3 (Sample 16):
      Fitness: {'live_cell_count': np.float64(0.7159452132609072), 'sum_dead_cell_count': np.float64(0.38833271268108394)}
      Parameters: {'apoptosis_rate': 5.763103537976935e-05, 'cell_cycle_entry': 1461.3241750226885}
   Point 4 (Sample 39):
      Fitness: {'live_cell_count': np.float64(0.8045753209307664), 'sum_dead_cell_count': np.float64(0.1938266989501782)}
      Parameters: {'apoptosis_rate': 5.6972530886514257e-05, 'cell_cycle_entry': 1526.73287646256}
   Point 5 (Sample 67):
      Fitness: {'live_cell_count': np.float64(0.8604650028634341), 'sum_dead_cell_count': np.float64(0.17346377711885388)}
      Parameters: {'cell_cycle_entry': 1491.7350835521092, 'apoptosis_rate': 6.063969176097474e-05}
../../_images/f450121627ef6c5ee44da9ea13ff9c1adf857843042abd81e18dd65c67ae6154.png

Visualize QoIs from Pareto front points

from uq_physicell.bo import plot_qoi_param
from mpl_toolkits.axes_grid1.inset_locator import inset_axes, mark_inset

fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(20, 12), sharex='col')
# Plot QoIs of best parameters
for i, qoi in enumerate(df_qois['QoI_Name']):
    print(f"Plotting {qoi}")
    ax_qoi = axes[0, i]
    ax_residual = axes[1, i]
    # Plot QoI values
    plot_qoi_param(df_obs_qoi, df_output, pareto_data['pareto_front']['sample_ids'], x_var='time', y_var=qoi, swarmplot=True, axis=ax_qoi)# 
    # Plot residuals
    plot_qoi_param(df_obs_qoi, df_output, pareto_data['pareto_front']['sample_ids'], x_var='time', y_var=qoi, swarmplot=True, axis=ax_residual, plot_residuals=True)#
    # Add zoomed-in inset in QoI plot
    if qoi == 'live_cell_count':
        # Insert a zoomed-in plot
        axins = inset_axes(ax_qoi, width="35%", height="35%", loc="lower right", bbox_to_anchor=(-0.01, 0.05, 1, 1), bbox_transform=ax_qoi.transAxes, borderpad=0.8)
        plot_qoi_param(df_obs_qoi, df_output, pareto_data['pareto_front']['sample_ids'], x_var='time', y_var=qoi, axis=axins)# 
        axins.set_xlim(6800,7000)
        axins.set_ylim(1900, 2000)
        axins.set(xlabel='', ylabel='')
        axins.get_legend().set_visible(False)
    else:
        # Insert a zoomed-in plot
        axins = inset_axes(ax_qoi, width="35%", height="35%", loc="lower left", bbox_to_anchor=(0.1, 0.05, 0.5, 1), bbox_transform=ax_qoi.transAxes, borderpad=0.8)
        plot_qoi_param(df_obs_qoi, df_output, pareto_data['pareto_front']['sample_ids'], x_var='time', y_var=qoi, swarmplot=True, axis=axins)#
        axins.set_xlim(-0.05, 0.05)
        axins.set_ylim(1025, 1075)
        axins.set(xlabel='', ylabel='')
        axins.get_legend().set_visible(False)
    mark_inset(ax_qoi, axins, loc1=2, loc2=4, fc="none", ec="0.5")

plt.savefig('QoIs_BO.svg', format='svg')
Plotting live_cell_count
Sample ID: [4, 13, 16, 39, 67]
Objective Function Values:
{'live_cell_count': np.float64(0.5649144394341963), 'sum_dead_cell_count': np.float64(0.8559025559873279)}
Noise of Objective Function:
{'live_cell_count': np.float64(0.22746576091514747), 'sum_dead_cell_count': np.float64(0.18779938784786435)}
Sample ID: [4, 13, 16, 39, 67]
Objective Function Values:
{'live_cell_count': np.float64(0.5649144394341963), 'sum_dead_cell_count': np.float64(0.8559025559873279)}
Noise of Objective Function:
{'live_cell_count': np.float64(0.22746576091514747), 'sum_dead_cell_count': np.float64(0.18779938784786435)}
Sample ID: [4, 13, 16, 39, 67]
Objective Function Values:
{'live_cell_count': np.float64(0.5649144394341963), 'sum_dead_cell_count': np.float64(0.8559025559873279)}
Noise of Objective Function:
{'live_cell_count': np.float64(0.22746576091514747), 'sum_dead_cell_count': np.float64(0.18779938784786435)}
Plotting sum_dead_cell_count
Sample ID: [4, 13, 16, 39, 67]
Objective Function Values:
{'live_cell_count': np.float64(0.5649144394341963), 'sum_dead_cell_count': np.float64(0.8559025559873279)}
Noise of Objective Function:
{'live_cell_count': np.float64(0.22746576091514747), 'sum_dead_cell_count': np.float64(0.18779938784786435)}
Sample ID: [4, 13, 16, 39, 67]
Objective Function Values:
{'live_cell_count': np.float64(0.5649144394341963), 'sum_dead_cell_count': np.float64(0.8559025559873279)}
Noise of Objective Function:
{'live_cell_count': np.float64(0.22746576091514747), 'sum_dead_cell_count': np.float64(0.18779938784786435)}
Sample ID: [4, 13, 16, 39, 67]
Objective Function Values:
{'live_cell_count': np.float64(0.5649144394341963), 'sum_dead_cell_count': np.float64(0.8559025559873279)}
Noise of Objective Function:
{'live_cell_count': np.float64(0.22746576091514747), 'sum_dead_cell_count': np.float64(0.18779938784786435)}
../../_images/adc09892b30be96272ba6966238aea6e121e85e33588c22988afc42f92204baa.png

Visualize QoI fitness vs parameter values

from uq_physicell.bo import plot_parameter_vs_fitness
# Plot each parameter vs each QoI
fig, axes = plt.subplots(len(df_param_space), len(df_qois['QoI_Name']), figsize=(12, 10))
fig.subplots_adjust(hspace=0.5, wspace=0.5)  # Increased spacing
for i, param in enumerate(df_param_space['ParamName']):
    for j, qoi in enumerate(df_qois['QoI_Name']):
        print(f"Plotting {param} vs {qoi}")
        plot_parameter_vs_fitness(df_samples, df_output, param, qoi, samples_id=pareto_data['pareto_front']['sample_ids'], axis= axes[i, j])
        # Plot real value
        axes[i, j].axvline(dic_real_value[param], color='red', linestyle='--', label='Real Value')

# Ensure proper layout and save the figure
plt.tight_layout()  # This will automatically adjust spacing to prevent overlaps
Plotting cell_cycle_entry vs live_cell_count
Plotting cell_cycle_entry vs sum_dead_cell_count
Plotting apoptosis_rate vs live_cell_count
Plotting apoptosis_rate vs sum_dead_cell_count
../../_images/15c33d34f22b9a5ec5afdc27746988fc6a15582dda7b24d65265c1bc8d83839e.png
from uq_physicell.bo.plots import plot_pareto_front
plot_pareto_front(df_output, 'live_cell_count', 'sum_dead_cell_count', samples_id=pareto_data['pareto_front']['sample_ids'], plot_std=True)
plt.savefig(f'Pareto_front_BO.svg', format='svg')
../../_images/5eae1f4666858373609072bfed6ca2294c04dd245527a14cf00be6f2b1d138fe.png
from uq_physicell.model_analysis import ModelAnalysisContext

db_path_post = "PostCalibData.db"
model_config_post = {"ini_path": "uq_config.ini", "struc_name": "ModelA"}

# For 'User-defined', params_info is metadata only — only ref_value is meaningful.
params_info = {
    "cell_cycle_entry": {"ref_value": 1440.0},
    "apoptosis_rate":   {"ref_value": 5.787e-05},
}

context = ModelAnalysisContext(db_path_post, model_config_post, "User-defined", params_info, qois_info={}, num_workers=8)

# Build sample dict from Pareto front points + the known ground truth (sample_id=0)
pareto_points = pareto_data['pareto_front']['sample_ids']
pareto_samples = (
    df_samples[df_samples['SampleID'].isin(pareto_points)]
    .pivot(index="SampleID", columns="ParamName", values="ParamValue")
    .to_dict(orient='index')
)
pareto_samples[0] = dic_real_value
context.set_samples(pareto_samples)

context.run()
Simulations completed and results stored in the database: PostCalibData.db.
from uq_physicell.model_analysis import load_output as load_output_ma
from uq_physicell.model_analysis import plot_cells_2D
import pandas as pd
import matplotlib.ticker as ticker

replicate_id = 0  # Assuming you want to load the first replicate
feature = 'current_cycle_phase_exit_rate'  # feature to plot in cmap
min_value = 0.0; max_value = 1/pd.DataFrame(context.dic_samples).T.min()['cell_cycle_entry']
df_qois_data_selected = load_output_ma(db_path_post, sample_ids=list(pareto_samples.keys())+[0], replicate_ids=[replicate_id], load_data=True)

# Dynamically set number of subplots to match number of samples
num_samples = len(list(pareto_samples.keys())+[0])
fig, axes = plt.subplots(1, num_samples, figsize=(4*num_samples, 5), sharex=True, sharey=True)

for ax_id, sample_id in enumerate(list(pareto_samples.keys())+[0]):
    mcds_timeseries = df_qois_data_selected[df_qois_data_selected['SampleID'] == sample_id].iloc[0]['Data']
    mcds_last_time = mcds_timeseries[-1] # Get the last time point of the time series for the current sample
    cumulative_death = qoi_functions['sum_dead_cell_count'](mcds_timeseries)
    df_cell = mcds_last_time.get_cell_df()
    if mcds_last_time.get_time() != 7200:
        print(f"Sample ID {sample_id} has last time {mcds_last_time.get_time()} instead of 7200")
    last_collection = plot_cells_2D(df_cell, ax=axes[ax_id], scale_bar=True if (ax_id==0) else False, feature=feature, cmap='viridis', vmin=min_value, vmax=max_value)
    axes[ax_id].set_title(f'Sample ID: {sample_id} - {len(df_cell)} cells\n Cumulative death: {cumulative_death}', fontsize=14)

# cbar = fig.colorbar(last_collection, ax=axes[-1], fraction=0.05, pad=0.02)    
fig.subplots_adjust(right=0.90)
cax = fig.add_axes([0.92, 0.15, 0.01, 0.7])  # [left, bottom, width, height]
cbar = fig.colorbar(last_collection, cax=cax)
# Configure the formatter to use scientific notation
formatter = ticker.ScalarFormatter(useMathText=True)
formatter.set_scientific(True)
formatter.set_powerlimits((-2, 2)) # Adjusts when sci-notation kicks in
cbar.ax.tick_params(labelsize=16)               # tick labels
cbar.ax.yaxis.get_offset_text().set_size(16)    # scientific notation text (e.g., ×10⁻³)
cbar.ax.yaxis.set_major_formatter(formatter)
cbar.set_label(feature)
# plt.tight_layout()
plt.savefig(f'last_snapshots_{feature}_pareto_points.svg', format='svg')
../../_images/545fc945c6e8ae09d4e43ed35e828dc6e051273bcf22c7c7c0689fa027cdf8eb.png

Next: ex10 applies the same analysis tools to a published pancreatic cancer invasion model, demonstrating rule inactivation sensitivity analysis across multiple initial conditions.