|
| 1 | +<!DOCTYPE html> |
| 2 | +<html lang="en"> |
| 3 | +<head> |
| 4 | + <meta charset="utf-8" /> |
| 5 | + <meta name="viewport" content="width=device-width, initial-scale=1" /> |
| 6 | + <title>Parameter Space · svVascularize Docs</title> |
| 7 | + |
| 8 | + <!-- Theme (match doc.html) --> |
| 9 | + <link href="https://fonts.googleapis.com/css?family=Montserrat:400,700" rel="stylesheet" /> |
| 10 | + <link rel="stylesheet" href="style.css" /> |
| 11 | + |
| 12 | + <!-- MathJax: render \( … \) and \[ … \]; ignore code/pre; provide argmin/argmax --> |
| 13 | + <script> |
| 14 | + window.MathJax = { |
| 15 | + tex: { |
| 16 | + inlineMath: [['\\(','\\)']], |
| 17 | + displayMath: [['\\[','\\]']], |
| 18 | + packages: {'[+]': ['base','ams']}, |
| 19 | + macros: { argmin: '\\operatorname*{arg\\,min}', argmax: '\\operatorname*{arg\\,max}' } |
| 20 | + }, |
| 21 | + options: { skipHtmlTags: ['script','noscript','style','textarea','pre','code'] } |
| 22 | + }; |
| 23 | + </script> |
| 24 | + <script defer src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js"></script> |
| 25 | +</head> |
| 26 | +<body> |
| 27 | + <!-- Top nav --> |
| 28 | + <header class="topnav"> |
| 29 | + <div class="container"> |
| 30 | + <h1>svVascularize</h1> |
| 31 | + <nav> |
| 32 | + <a href="index.html#about">About</a> |
| 33 | + <a href="install.html">Installation</a> |
| 34 | + <a class="active" href="doc.html">Documentation</a> |
| 35 | + <a href="index.html#simulation">Simulation</a> |
| 36 | + <a href="https://pypi.org/project/svv/" target="_blank" rel="noopener">PyPI</a> |
| 37 | + <a href="https://github.com/SimVascular/svVascularize" target="_blank" rel="noopener">GitHub</a> |
| 38 | + </nav> |
| 39 | + </div> |
| 40 | + </header> |
| 41 | + |
| 42 | + <!-- Hero --> |
| 43 | + <section class="hero"> |
| 44 | + <div class="container"> |
| 45 | + <h2>Parameter Space & Sampling</h2> |
| 46 | + <p>Generate diverse vascular trees by exploring objective weights, constraints, sampling, and stochastic seeds.</p> |
| 47 | + <a class="cta" href="doc.html">Back to Docs</a> |
| 48 | + </div> |
| 49 | + </section> |
| 50 | + |
| 51 | + <main class="container content"> |
| 52 | + <h2 id="overview">Overview</h2> |
| 53 | + <p> |
| 54 | + <strong>svVascularize</strong> exposes a set of parameters that control how trees grow, how candidates are proposed, |
| 55 | + which constraints are enforced, and how the local optimization balances competing criteria. |
| 56 | + By sweeping these parameters and varying random seeds, you can produce families of trees tailored to |
| 57 | + specific tissues, printing constraints, or hemodynamic goals. |
| 58 | + </p> |
| 59 | + |
| 60 | + <div class="callout tip"> |
| 61 | + Think of a run as \( \mathcal{T}(\theta, s) \): a tree produced from a parameter vector \( \theta \) and RNG seed \( s \). |
| 62 | + Exploring the space means scanning \( \theta \) (and replicates over \( s \)) to map design → outcome. |
| 63 | + </div> |
| 64 | + |
| 65 | + <h2 id="controls">Key controls</h2> |
| 66 | + <table> |
| 67 | + <thead> |
| 68 | + <tr><th>Category</th><th>Parameters (examples)</th><th>Effect</th></tr> |
| 69 | + </thead> |
| 70 | + <tbody> |
| 71 | + <tr> |
| 72 | + <td><strong>Domain & seeds</strong></td> |
| 73 | + <td>geometry (mesh/SDF), inlets/outlets, root pose, initial terminals</td> |
| 74 | + <td>Where growth is allowed; initial topology & bias.</td> |
| 75 | + </tr> |
| 76 | + <tr> |
| 77 | + <td><strong>Demand & targets</strong></td> |
| 78 | + <td>terminal count, volumetric demand field, sampling scheme (uniform / blue-noise / demand-weighted)</td> |
| 79 | + <td>Space-filling behavior; coverage uniformity; perfusion targeting.</td> |
| 80 | + </tr> |
| 81 | + <tr> |
| 82 | + <td><strong>Objective weights</strong></td> |
| 83 | + <td>\(J = \alpha\,\text{Power} + \beta\,\text{Volume} + \gamma\,\text{Smoothness} + \dots\)</td> |
| 84 | + <td>Trade-off energy vs. material vs. geometry.</td> |
| 85 | + </tr> |
| 86 | + <tr> |
| 87 | + <td><strong>Murray / flow model</strong></td> |
| 88 | + <td>exponent \( n \in [2.7,3.2] \), viscosity model, Poiseuille/0D options</td> |
| 89 | + <td>Radius scaling at bifurcations; shear/pressure profiles.</td> |
| 90 | + </tr> |
| 91 | + <tr> |
| 92 | + <td><strong>Hard constraints</strong></td> |
| 93 | + <td>clearance, non-intersection, domain inclusion, degree limits, min length</td> |
| 94 | + <td>Feasibility filter; shapes admissible solutions.</td> |
| 95 | + </tr> |
| 96 | + <tr> |
| 97 | + <td><strong>Soft constraints</strong></td> |
| 98 | + <td>angle bounds, taper/smoothness penalties, curvature limits</td> |
| 99 | + <td>Regularity of geometry; printability robustness.</td> |
| 100 | + </tr> |
| 101 | + <tr> |
| 102 | + <td><strong>Local optimization</strong></td> |
| 103 | + <td>neighborhood size, line-search/trust-region, tolerance, max iters</td> |
| 104 | + <td>Quality/speed of bifurcation placement & sizing.</td> |
| 105 | + </tr> |
| 106 | + <tr> |
| 107 | + <td><strong>Stochasticity</strong></td> |
| 108 | + <td>RNG seed, candidate pool size, tempered acceptance, resample policy</td> |
| 109 | + <td>Diversity and exploration vs. exploitation.</td> |
| 110 | + </tr> |
| 111 | + </tbody> |
| 112 | + </table> |
| 113 | + |
| 114 | + <h2 id="objective">Objective & constraints (at a glance)</h2> |
| 115 | + <p> |
| 116 | + We typically minimize a penalized composite objective: |
| 117 | + </p> |
| 118 | + <div class="mathblock"> |
| 119 | + \[ |
| 120 | + J(\mathcal{T}) = \alpha \sum_i R_i Q_i^2 \;+\; \beta\,\text{Volume}(\mathcal{T}) \;+\; \gamma\,\text{Smooth}(\mathcal{T}) |
| 121 | + \;+\; \sum_k \lambda_k\,\phi_k(\mathcal{T}), |
| 122 | + \] |
| 123 | + </div> |
| 124 | + <p class="muted"> |
| 125 | + Here \(R_i\) are segment resistances (Poiseuille), \(Q_i\) flows from a fast 0D solve per candidate, and \(\phi_k\) are soft-constraint penalties; |
| 126 | + Murray-like scaling \(r_0^{\,n}=r_1^{\,n}+r_2^{\,n}\) is enforced exactly or with a strong penalty during local refinement. |
| 127 | + Hard constraints (clearance, non-intersection, domain inclusion) act as feasibility filters before scoring. |
| 128 | + </p> |
| 129 | + |
| 130 | + <h2 id="sweeps">How to explore the space</h2> |
| 131 | + <ul> |
| 132 | + <li><strong>Grid / factorial sweep:</strong> Small dimensionality, coarse mapping of sensitivities.</li> |
| 133 | + <li><strong>Random / Sobol / Latin Hypercube:</strong> Space-filling samples for moderate/high dimensions.</li> |
| 134 | + <li><strong>Annealed sweeps:</strong> Start with relaxed constraints; tighten over stages to avoid stalls.</li> |
| 135 | + <li><strong>Replicates:</strong> For each \( \theta \), run \( s=1..R \) seeds to estimate variability and robustness.</li> |
| 136 | + <li><strong>Pareto fronts:</strong> When tuning \((\alpha,\beta,\gamma)\), track non-dominated solutions (e.g., power vs volume).</li> |
| 137 | + </ul> |
| 138 | + |
| 139 | + <h2 id="workflow">A practical sweep workflow</h2> |
| 140 | + <ol> |
| 141 | + <li><strong>Define</strong> your domain, inlet/outlet sites, and a base parameter template \( \theta_0 \).</li> |
| 142 | + <li><strong>Choose</strong> sweep axes (e.g., Murray exponent \(n\), terminal demand \(q_{\text{term}}\), angle penalty \(\gamma_{\angle}\)).</li> |
| 143 | + <li><strong>Sample</strong> \( \Theta = \{\theta^{(1)},\ldots,\theta^{(M)}\} \) (grid, Sobol, etc.) and replicates \( s=1..R \).</li> |
| 144 | + <li><strong>Generate</strong> trees \(\mathcal{T}(\theta^{(m)}, s)\); record metrics.</li> |
| 145 | + <li><strong>Select</strong> candidates by constraints + objective, or compute a Pareto set for multi-objective trade-offs.</li> |
| 146 | + </ol> |
| 147 | + |
| 148 | + <h3 id="code">Illustrative sweep (pseudo-API)</h3> |
| 149 | + <p class="muted">This mirrors typical svVascularize usage; adjust names to your actual API.</p> |
| 150 | + <pre data-copy><code class="language-python">import itertools, json, pathlib, numpy as np |
| 151 | + |
| 152 | +# 1) Base parameters |
| 153 | +base = dict( |
| 154 | + domain="heart_slice.sdf", # or mesh |
| 155 | + inlets=[(12.0, 6.1, 4.7)], |
| 156 | + outlets=[], # optional; use forest-connection for loops |
| 157 | + terminals=1200, |
| 158 | + sampling="blue-noise", |
| 159 | + murray_n=3.0, |
| 160 | + weights=dict(alpha_power=1.0, beta_volume=0.1, gamma_smooth=0.05), |
| 161 | + constraints=dict(clearance=0.12, min_length=0.4, angle_min=25, angle_max=120), |
| 162 | + local_opt=dict(neighborhood=3.0, max_iters=20, tol=1e-3), |
| 163 | +) |
| 164 | + |
| 165 | +# 2) Define a sweep over two axes + RNG replicates |
| 166 | +n_vals = [2.8, 3.0, 3.2] |
| 167 | +q_vals = [0.8, 1.0, 1.2] # relative terminal demand scale (example) |
| 168 | +seeds = [11, 12, 13] |
| 169 | + |
| 170 | +def paramsets(): |
| 171 | + for n, q in itertools.product(n_vals, q_vals): |
| 172 | + p = json.loads(json.dumps(base)) # deep-ish copy |
| 173 | + p["murray_n"] = n |
| 174 | + p["demand_scale"] = q |
| 175 | + yield p |
| 176 | + |
| 177 | +# 3) Run |
| 178 | +outdir = pathlib.Path("runs/param_sweep") |
| 179 | +outdir.mkdir(parents=True, exist_ok=True) |
| 180 | + |
| 181 | +for i, theta in enumerate(paramsets()): |
| 182 | + for s in seeds: |
| 183 | + theta["seed"] = s |
| 184 | + # v = svv.Vascularizer(theta) # construct |
| 185 | + # T = v.grow() # generate tree |
| 186 | + # metrics = v.metrics() # coverage, collisions, power, volume, etc. |
| 187 | + # v.save(outdir / f"tree_{i}_seed{s}.vtp") # geometry |
| 188 | + # json.dump(metrics, open(outdir / f"tree_{i}_seed{s}.json","w"), indent=2) |
| 189 | + pass # replace with real calls |
| 190 | + |
| 191 | +# 4) Post-process: aggregate metrics and rank / build Pareto set |
| 192 | +</code></pre> |
| 193 | + |
| 194 | + <h2 id="metrics">What to measure</h2> |
| 195 | + <table> |
| 196 | + <thead> |
| 197 | + <tr><th>Metric</th><th>Why it matters</th></tr> |
| 198 | + </thead> |
| 199 | + <tbody> |
| 200 | + <tr><td>Coverage (%) / voids</td><td>Uniform perfusion and space-filling behavior.</td></tr> |
| 201 | + <tr><td>Collisions / clearance violations</td><td>Feasibility and printability.</td></tr> |
| 202 | + <tr><td>Total power & volume</td><td>Energy vs. material trade-off in \(J\).</td></tr> |
| 203 | + <tr><td>Radius & length distributions</td><td>Physiological realism / manufacturability.</td></tr> |
| 204 | + <tr><td>Bifurcation angles / taper</td><td>Geometric regularity and flow quality.</td></tr> |
| 205 | + <tr><td>Shear & pressure ranges</td><td>Hemodynamic safety windows.</td></tr> |
| 206 | + <tr><td>Connectivity / loops (forest)</td><td>Closed-circuit perfusion for tissues.</td></tr> |
| 207 | + </tbody> |
| 208 | + </table> |
| 209 | + |
| 210 | + <h2 id="defaults">Starting ranges (tunable)</h2> |
| 211 | + <ul> |
| 212 | + <li><strong>Murray exponent</strong> \(n \in [2.7, 3.2]\)</li> |
| 213 | + <li><strong>Angle bounds</strong> \([20^\circ, 120^\circ]\) with a soft penalty beyond</li> |
| 214 | + <li><strong>Clearance</strong> \(0.05\text{–}0.2\) × local radius scale (domain-dependent)</li> |
| 215 | + <li><strong>Min segment length</strong> \(0.3\text{–}1.0\) × voxel/feature size</li> |
| 216 | + <li><strong>Objective weights</strong> start \((\alpha,\beta,\gamma)=(1,0.1,0.05)\), then tune by Pareto analysis</li> |
| 217 | + </ul> |
| 218 | + |
| 219 | + <div class="callout warning"> |
| 220 | + Over-tight constraints can stall growth. Use <em>progressive tightening</em> (anneal clearance/angles) or multi-resolution domains. |
| 221 | + </div> |
| 222 | + |
| 223 | + <h2 id="repro">Reproducibility checklist</h2> |
| 224 | + <ul> |
| 225 | + <li>Record: parameter vector \( \theta \), RNG seed \( s \), commit hash / version, domain asset checksums.</li> |
| 226 | + <li>Persist: metrics JSON + geometry artifacts (e.g., VTP/VTK) for each run.</li> |
| 227 | + <li>Log: accept/reject counts, constraint violations, local-opt iterations (helps diagnose stalls).</li> |
| 228 | + </ul> |
| 229 | + |
| 230 | + <h2 id="next">Next steps</h2> |
| 231 | + <ul> |
| 232 | + <li><a href="algorithm.html">Algorithm & local optimization</a></li> |
| 233 | + <li><a href="validation.html">Validation: geometric & hemodynamic checks</a></li> |
| 234 | + </ul> |
| 235 | + </main> |
| 236 | + |
| 237 | + <footer> |
| 238 | + <div class="container"> |
| 239 | + <p>© 2025 SimVascular, Stanford University, The Regents of the University of California, and others — |
| 240 | + <a href="https://opensource.org/license/BSD-3-Clause" target="_blank" rel="noopener">BSD 3-Clause License</a> |
| 241 | + </p> |
| 242 | + </div> |
| 243 | + </footer> |
| 244 | + |
| 245 | + <script defer src="script.js"></script> |
| 246 | +</body> |
| 247 | +</html> |
0 commit comments