Add svZeroDTuner application#220
Conversation
…essure and tuning LV:Emax, using Nelder-Mead
…y control-c, expose more options for differential_evolution
…orks pretty well for 3 parameters and two targets
…t_all_cycles to true (makes optimization much faster)
…put in simulation.py
…low initial conditions as tunable parameters, print optimization termination reason for transparency, add complex tuning task for closed loop model
…t tuning_complex.yaml example
…talling from source
…s. target data to csv
…zed l2 error, remove other objective function types that weren't even implemented to begin with
… function to only penalize simulated values outside of target range.
… to optimization function, with only simple numeric coersion. Also, remove support for all algorithm except nelder-mead and differential-evolution
…early termination if objective function is zero. Use "iteration" for both differential_evolution and Nelder-Mead, don't keep track of every function evaluation for Nelder-Mead.
…ain.py to suggest Baseline, Sensitivity, then Optimize modes
…llow target file csvs for examples in git repo
…into SimVascular-master
…activation changes
…ore upstream resistances)
…aper). Also, use Nelder-Mead
…30, increase job time to 3 hours
…th pickle-safe objective wrapper; make SV0DTuner pickle-safe for multiprocessing.
…alse. Use 32 tasks
…lative_bounds' - Updated YAML configuration files across various examples to use 'relative_bounds' instead of 'uncertainty' for defining target tolerances. - Modified the ConfigHandler to validate the new 'relative_bounds' field and ensure compatibility with legacy 'uncertainty'. - Adjusted the ObjectiveFunction to handle 'relative_bounds' in the computation of target ranges. - Enhanced documentation to reflect changes in configuration schema and usage examples. - Added new SVG diagrams to illustrate the YAML structure and workflow of svZeroDTuner. - Created comprehensive troubleshooting and concepts documentation for better user guidance.
- Refactor command-line usage in main.py for clarity on running baseline and optimization modes. - Update README and YAML files to reflect new command-line syntax for running baseline and optimization. - Improve documentation in right_heart_pa example for better user guidance on running the model.
There was a problem hiding this comment.
Pull request overview
This PR introduces svZeroDTuner, a new Python package and CLI intended to provide a YAML-driven workflow for calibrating svZeroDSolver 0D models against scalar and time-series targets, along with sensitivity screening utilities, documentation, examples, and regression tests.
Changes:
- Adds the
svzerodtunerPython package (optimization/sensitivity orchestration, config/parameter handling, expressions/objectives, plotting/reporting). - Registers a new CLI entry point (
svzerodtuner) and updates runtime dependencies. - Adds extensive documentation pages plus multiple real-world example workflows (configs, scripts, target CSVs).
Reviewed changes
Copilot reviewed 62 out of 63 changed files in this pull request and generated 13 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/test_svzerodtuner.py | Adds regression tests for tuner dependency declarations, config validation, parameter validation, and sensitivity behaviors. |
| setup.cfg | Declares the new package, installs tuner runtime deps, and adds the svzerodtuner console script entry point. |
| docs/pages/tuner.md | Adds the main svZeroDTuner user guide page. |
| docs/pages/tuner_api.md | Documents CLI commands and Python APIs exposed by the tuner package. |
| docs/pages/tuner_concepts.md | Explains tuning concepts (targets, ranges, norms, bounds/scaling, failure modes). |
| docs/pages/tuner_configuration.md | Defines YAML schemas and validation rules for optimization and sensitivity configs. |
| docs/pages/tuner_examples.md | Provides worked example workflows and expected outputs. |
| docs/pages/tuner_troubleshooting.md | Adds troubleshooting guidance for common tuning issues. |
| docs/pages/main.md | Links svZeroDTuner guide from docs main page. |
| docs/pages/developer_guide.md | Adds svZeroDTuner references into the developer guide docs navigation. |
| applications/svZeroDTuner/svzerodtuner/init.py | Defines the package and its version. |
| applications/svZeroDTuner/svzerodtuner/cli.py | Implements svzerodtuner CLI command parsing and dispatch. |
| applications/svZeroDTuner/svzerodtuner/config_handler.py | Adds YAML loading, path resolution, and validation for optimization configs. |
| applications/svZeroDTuner/svzerodtuner/expression_handler.py | Adds expression compilation/evaluation for extracting outputs and defining targets/QoIs. |
| applications/svZeroDTuner/svzerodtuner/objective.py | Implements range-based objective computation for scalar and time-series targets. |
| applications/svZeroDTuner/svzerodtuner/optimizer.py | Wraps SciPy optimizers (Nelder-Mead / differential evolution), history, scaling, callbacks, and early termination. |
| applications/svZeroDTuner/svzerodtuner/output_extractor.py | Provides helpers for extracting solver outputs by exact result names. |
| applications/svZeroDTuner/svzerodtuner/parameter_handler.py | Implements model parameter get/set by Block.Parameter naming. |
| applications/svZeroDTuner/svzerodtuner/result_handler.py | Saves histories/results and generates summary outputs/plots. |
| applications/svZeroDTuner/svzerodtuner/scaling.py | Adds parameter scaling transforms between physical and optimizer spaces. |
| applications/svZeroDTuner/svzerodtuner/sensitivity.py | Implements correlation-based screening using Sobol sampling and reporting/visualization. |
| applications/svZeroDTuner/svzerodtuner/simulation.py | Centralizes simulation execution used by both optimization and sensitivity flows. |
| applications/svZeroDTuner/svzerodtuner/sv0d_tuner.py | Orchestrates end-to-end optimization runs, objective evaluation, result saving, and reporting. |
| applications/svZeroDTuner/svzerodtuner/visualization.py | Adds plotting utilities for history, parameters, targets, and full simulation outputs. |
| applications/svZeroDTuner/requirements.txt | Provides a tuner-specific requirements list for example usage. |
| applications/svZeroDTuner/.gitignore | Ignores generated tuner example artifacts (baseline/results folders). |
| applications/svZeroDTuner/examples/right_heart_pa/README.md | Documents the right-heart/pulmonary-artery tuning example workflow. |
| applications/svZeroDTuner/examples/right_heart_pa/main.py | Adds baseline/optimize/sensitivity driver script for the right_heart_pa example. |
| applications/svZeroDTuner/examples/right_heart_pa/tuning_differential_evolution.yaml | Differential evolution tuning config for right_heart_pa example. |
| applications/svZeroDTuner/examples/right_heart_pa/tuning_nelder_mead.yaml | Nelder-Mead tuning config for right_heart_pa example. |
| applications/svZeroDTuner/examples/closed_loop_Zingaro/main.py | Adds baseline/optimize/sensitivity driver script for the Zingaro closed-loop example. |
| applications/svZeroDTuner/examples/closed_loop_Zingaro/model.json | Adds the closed-loop Zingaro example model JSON. |
| applications/svZeroDTuner/examples/closed_loop_Zingaro/sensitivity.yaml | Sensitivity screening config for the Zingaro example. |
| applications/svZeroDTuner/examples/closed_loop_Zingaro/tuning.yaml | Optimization config for the Zingaro example. |
| applications/svZeroDTuner/examples/closed_loop_Zingaro/tuning_job.sh | Adds an HPC batch script template for running tuning on a cluster. |
| applications/svZeroDTuner/examples/closed_loop_Zingaro/targets/P003_chamber_volumes/convert_volume_data.py | Utility to convert volume CSVs to tuner target CSV format. |
| applications/svZeroDTuner/examples/closed_loop_Zingaro/targets/P003_chamber_volumes/la_volume_manual.csv | Adds LA volume reference data (manual). |
| applications/svZeroDTuner/examples/closed_loop_Zingaro/targets/P003_chamber_volumes/target_V_LA.csv | Adds time-series target for LA volume. |
| applications/svZeroDTuner/examples/closed_loop_Zingaro/targets/P003_chamber_volumes/target_V_LV.csv | Adds time-series target for LV volume. |
| applications/svZeroDTuner/examples/closed_loop_Zingaro/targets/P003_chamber_volumes/target_V_RA.csv | Adds time-series target for RA volume. |
| applications/svZeroDTuner/examples/closed_loop_Zingaro/targets/P003_chamber_volumes/target_V_RV.csv | Adds time-series target for RV volume. |
| applications/svZeroDTuner/examples/closed_loop_Zingaro/targets/P003_chamber_volumes/volume.csv | Adds source volume dataset used by conversion utility. |
| applications/svZeroDTuner/examples/closed_loop_Regazzoni/main.py | Adds baseline/optimize/sensitivity driver script for the Regazzoni closed-loop example. |
| applications/svZeroDTuner/examples/closed_loop_Regazzoni/model.json | Adds the closed-loop Regazzoni example model JSON. |
| applications/svZeroDTuner/examples/closed_loop_Regazzoni/sensitivity.yaml | Sensitivity screening config for the Regazzoni example. |
| applications/svZeroDTuner/examples/closed_loop_Regazzoni/tuning_complex.yaml | More comprehensive optimization config for the Regazzoni example. |
| applications/svZeroDTuner/examples/closed_loop_Regazzoni/tuning_differential_evolution.yaml | Differential evolution tuning config for the Regazzoni example. |
| applications/svZeroDTuner/examples/closed_loop_Regazzoni/tuning_job.sh | Adds an HPC batch script template for running tuning on a cluster. |
| applications/svZeroDTuner/examples/closed_loop_Regazzoni/tuning_nelder_mead.yaml | Nelder-Mead tuning config for the Regazzoni example. |
| applications/svZeroDTuner/examples/closed_loop_Regazzoni/tuning_time_series_target.yaml | Demonstrates a time-series target matching configuration. |
| applications/svZeroDTuner/examples/closed_loop_Regazzoni/targets/create_target_from_baseline.py | Utility to create time-series targets from baseline results. |
| applications/svZeroDTuner/examples/closed_loop_Regazzoni/targets/target_pressure_ar_sys.csv | Example time-series target CSV for arterial pressure. |
| applications/svZeroDTuner/examples/closed_loop_Regazzoni/targets/P003_chamber_volumes/convert_volume_data.py | Utility to convert chamber volume data to tuner target CSV format. |
| applications/svZeroDTuner/examples/closed_loop_Regazzoni/targets/P003_chamber_volumes/la_volume_manual.csv | Adds LA volume reference data (manual). |
| applications/svZeroDTuner/examples/closed_loop_Regazzoni/targets/P003_chamber_volumes/target_V_LA.csv | Adds time-series target for LA volume. |
| applications/svZeroDTuner/examples/closed_loop_Regazzoni/targets/P003_chamber_volumes/target_V_LV.csv | Adds time-series target for LV volume. |
| applications/svZeroDTuner/examples/closed_loop_Regazzoni/targets/P003_chamber_volumes/target_V_RA.csv | Adds time-series target for RA volume. |
| applications/svZeroDTuner/examples/closed_loop_Regazzoni/targets/P003_chamber_volumes/target_V_RV.csv | Adds time-series target for RV volume. |
| applications/svZeroDTuner/examples/closed_loop_Regazzoni/targets/P003_chamber_volumes/volume.csv | Adds source volume dataset used by conversion utility. |
| README.md | Adds a documentation link to the tuner guide and removes CI/coverage badges. |
| .gitignore | Un-ignores target CSVs under tuner examples while keeping global CSV ignore. |
| .github/workflows/test.yml | Adjusts Windows CI Python deps to include PyYAML (for tuner configs). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| svzerodtuner | ||
| package_dir = | ||
| svzerodtuner = applications/svZeroDTuner/svzerodtuner | ||
| python_requires = >=3.0 |
| shell: pwsh | ||
| run: | | ||
| python -m pip install --upgrade cmake cmake-setuptools numpy ninja pytest pandas graphviz networkx pydot | ||
| python -m pip install --upgrade cmake cmake-setuptools numpy ninja pytest pandas graphviz networkx pydot pyyaml |
| lo, hi = float(bounds[0]), float(bounds[1]) | ||
| self._max_bound = max(lo, hi) | ||
| if self._max_bound == 0: | ||
| raise ValueError("Max scaling requires non-zero bounds") |
| try: | ||
| analyzer.run_analysis() | ||
| except Exception as e: |
| try: | ||
| pct = float(unc.strip()[:-1]) | ||
| if pct < 0: | ||
| raise ValueError( | ||
| f"Target '{target['name']}' relative_bounds percent must be non-negative" |
| "<expr>", | ||
| "exec", | ||
| ) | ||
| exec(code, namespace) |
| except Exception as e: | ||
| # Return large value if simulation fails | ||
| print(f"Warning: Simulation failed: {e}") | ||
| return float(1e10) |
| import matplotlib.pyplot as plt | ||
| import matplotlib | ||
| matplotlib.use('Agg') | ||
| except ImportError: |
|
|
||
| [](https://github.com/simvascular/svZeroDSolver/actions) | ||
| [](https://codecov.io/gh/SimVascular/svZeroDSolver) | ||
| [](https://github.com/simvascular/svZeroDSolver/releases/latest) | ||
|  |
| # Send an email to this address when your job starts and finishes | ||
| #SBATCH --mail-user=abrown97@stanford.edu | ||
| #SBATCH --mail-type=begin | ||
| #SBATCH --mail-type=fail | ||
| #SBATCH --mail-type=end |
mrp089
left a comment
There was a problem hiding this comment.
Nice application! I had some ideas for the documentation and examples.
| - Post-processing and network inspection (use [svZeroDVisualization](@ref visualization)) | ||
| - Fundamental model-structure changes (update the model itself first) | ||
|
|
||
| # Quickstart |
There was a problem hiding this comment.
Many helpful sub-pages are listed under Related Tools, which can make it hard to find. Link these more visibly at the top.
|
|
||
| [](https://github.com/simvascular/svZeroDSolver/actions) | ||
| [](https://codecov.io/gh/SimVascular/svZeroDSolver) | ||
| [](https://github.com/simvascular/svZeroDSolver/releases/latest) | ||
|  |
| Run optimization: | ||
|
|
||
| ```bash | ||
| svzerodtuner optimize applications/svZeroDTuner/examples/right_heart_pa/tuning_differential_evolution.yaml |
There was a problem hiding this comment.
This example takes a long time to run (107 iterations with 55,314 function evals). Is this setup correct? Is there a more straightforward first example users can run? Is this a synthetic example where we should recover the exact parameters (and do we)?
|
|
||
| ## CLI workflow | ||
|
|
||
| Run optimization: |
There was a problem hiding this comment.
Would be helpful to showcase some useful outputs users can expect, maybe in individual example readmes, and link them here.
| Run sensitivity analysis: | ||
|
|
||
| ```bash | ||
| svzerodtuner sensitivity-analysis applications/svZeroDTuner/examples/closed_loop_Regazzoni/sensitivity.yaml |
There was a problem hiding this comment.
Same as above, what is computed here, what output do we get, does it make sense?
|
|
||
| # Workflow | ||
|
|
||
| A typical svZeroDTuner workflow is: |
There was a problem hiding this comment.
How do the tools optimize and sensitivity tie in here?
|
|
||
| # Convergence and Termination | ||
|
|
||
| svZeroDTuner currently supports: |
There was a problem hiding this comment.
Why only those two? Can you link to the scipy functions this is built on?
| - `differential_evolution` | ||
| - `Nelder-Mead` | ||
|
|
||
| Optimization options are passed through to SciPy using native option names. |
There was a problem hiding this comment.
Can you say something about those two optimization methods and when to use them?
|
|
||
| [TOC] | ||
|
|
||
| # What Is Being Tuned |
There was a problem hiding this comment.
Can you provide some fundamental math of what's being solved using arg min, etc.?
| @@ -0,0 +1,71 @@ | |||
| @page tuner_concepts svZeroDTuner Concepts | |||
There was a problem hiding this comment.
I couldn't find anything behind the math for the sensitivity analysis. What is being computed? What do the sensitivity values mean? Is there a literature reference?
Current situation
This PR adds
svZeroDTuner, a new Python package and CLI for calibratingsvZeroDSolver0D models against scalar and time-series targets. It introduces a YAML-driven tuning workflow, sensitivity analysis utilities, example configurations, documentation, and test coverage. The goal with this new application is to create an intuitive and scalable workflow for deterministic optimization of 0D models. @aabrown100-git and I have been working on this after multiple requests from the lab and specifically to address #158.Release Notes
svzerodtunerpackage underapplications/svZeroDTunersvzerodtuneroptimize/runfor optimizationsensitivity-analysis/sensitivityfor screening studiesNelder-Meadanddifferential_evolutionmethodsrelative_boundsL1andL2objective normsidentity,log,max)closed_loop_Regazzoniclosed_loop_Zingaroright_heart_paDocumentation
We have added extensive tuner documentation spanning tuning overview, relevant concepts, tuner configuration, examples, API and troubleshooting.
Testing
added
test_svzerodtuner.pywhich covers svZeroDTuner I/O functions.Code of Conduct & Contributing Guidelines