FORGE Studio Interface
This page pins the stable public surface FORGE Studio (and any other downstream consumer) builds against, and lists what is explicitly internal. It exists so the boundary stays clean: if a symbol is not on this page, it may change or disappear without notice.
Stability policy: changes to this surface are additive by default (new optional opts keys, new optional stats fields, new keyword arguments). A breaking change to anything documented here requires a design doc in docs/superpowers/specs/ and an explicit note in the PR that lands it. FORGE Studio vendors Sentinel from mechneurolab/sentinel main.
1. Sentinel.invert — the inversion façade
The single programmatic entry point for the FORGE/EMPIRE inversion stage:
Sentinel.invert(mat_path::AbstractString; opts::NamedTuple,
on_iteration = nothing) -> NamedTupleRuns a complete MRE inverse reconstruction from a UIUC-format .mat displacement file: mesh generation, setup, zone-decomposition solve, and interpolation of the reconstructed complex shear modulus back onto the image voxel grid.
opts schema
Required:
| key | type | meaning |
|---|---|---|
material_model | String | "isotropic", "orthotropic", "isotropic_compressible", "poroelastic", "transverse_isotropic", or "generalized_anisotropic" |
regularization | String | "total_variation", "tikhonov", "spatial_filter", "van_houten", "marquardt", "joachimowicz", "soft_prior", or "force_balance" |
frequency_hz | Real | actuation frequency (Hz) |
Optional (defaults in parentheses):
| key | type | meaning |
|---|---|---|
reg_weight | Real | active-regularizer weight — native units for TV-style penalties (5e-16); fraction of initial data misfit for force_balance (0.1) |
density_kg_m3 | Real | tissue density (1000.0) |
max_global_iters | Int | global iteration cap (20) |
mesh_resolution | Int | hex-mesh strategy 1/2/3 (1) |
linear_solver | String | "mumps" / "krylov" / "direct"; anything else → solver default (cached direct) |
compute_backend | String | gradient/zone device: "auto" / "metal" / "cuda" / "cpu" ("auto") |
serial | Bool | force serial zone solves (false) |
Unknown keys are ignored; adding new optional keys is a non-breaking change.
on_iteration callback
Called once per global iteration, after zone consolidation:
(giter::Int, objective::Float64, disp_error::Float64,
converged::Bool, mean_shear_kpa::Float64)mean_shear_kpa is the mean reconstructed shear-stiffness magnitude
Return value
(; real_shear, imag_shear, voxel_size, dims, stats):
real_shear,imag_shear—Array{Float64,3}, storage/loss shear modulus (Pa) on the original image voxel grid. Voxels outside the reconstructed domain areNaN(deliberate "no reconstruction" sentinel — do not assume finite arrays; a0.0background would corruptloss_angle = atand(imag, real)).voxel_size::NTuple{3,Float64}— image voxel size (mm).dims::NTuple{3,Int}—size(real_shear).stats::NamedTuple— for the inversion-QA sidecar:converged::Bool,iterations::Int,max_iterations::Int,final_objective::Float64,final_disp_error::Float64,mesh_elements::Int,mesh_nodes::Int. Every field is optional on the FORGE side; new fields may be added.
2. High-level configuration API
The public configuration model is InversionProblem — the single validated description of a reconstruction — plus:
solve(prob; basedir, on_iteration, kwargs...) -> InversionResult(alsosolve(path)for a config file).load_inversion(path) -> InversionProblem— reads both TOML configurations and legacy Fortran.datrunfiles (dispatch on the.datextension).save_inversion(path, prob)— TOML, provenance-grade.runfile_to_toml(dat[, toml])— explicit format converter.InversionResultfields:material,displacement,state,problem,setup.Post-processing:
export_reconprops,interpolate_to_grid,export_vtk.
solve writes a fully-resolved "<output>.config.toml" next to the outputs for provenance.
3. CLI
The sentinel CLI (sentinel invert|validate|convert|forward|mesh) is public surface; invert and validate accept both .toml and .dat inputs. See the CLI guide.
4. Extension seams
Sentinel's GPU packages override these internal hooks from package extensions (FORGE Studio's bundled CUDA/Metal extensions use the same seams):
Sentinel._gpu_ka_backend(::Val{:metal|:cuda})— gradient-device discovery consulted byselect_parallel_strategy.Sentinel.AbstractLinearSolversubtyping +Sentinel.linear_solve/Sentinel.invalidate_cachefor solver backends.
These are underscore-/internal-named on purpose: they are stable for coordinated extension development, not general API. Changes are announced in PR descriptions.
5. Explicitly internal (do not depend on these)
Everything not listed above is internal; in particular, after Phase 2 of the native-config migration these are un-exported implementation details:
InverseRunfileConfig,RegularizationConfig— private output/validator structs of the.datparser.parse_inverse_runfile,raise_config— internal steps ofload_inversion(".dat").build_reg_config— the constructor's internal cross-spec validator.SolveConfig,RegBuildContext,build_regularizer— setup internals behindsetup_inverse_problem.Zone drivers, batched solvers, gradient backends, and everything under
src/distributed/— reachable for power users viarun_inverse_solve!kwargs, but their signatures are not pinned.
Historical note: before Phase 2, .dat handling flowed through a public InverseRunfileConfig; that type no longer appears anywhere in the public surface. If FORGE-side code ever needs a config field, read it from the InversionProblem (load_inversion both formats) instead.