◆ FORGE Suite
GitHubMechanical Neuroimaging Lab · Univ. of Delaware
Skip to content

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:

julia
Sentinel.invert(mat_path::AbstractString; opts::NamedTuple,
                on_iteration = nothing) -> NamedTuple

Runs 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:

keytypemeaning
material_modelString"isotropic", "orthotropic", "isotropic_compressible", "poroelastic", "transverse_isotropic", or "generalized_anisotropic"
regularizationString"total_variation", "tikhonov", "spatial_filter", "van_houten", "marquardt", "joachimowicz", "soft_prior", or "force_balance"
frequency_hzRealactuation frequency (Hz)

Optional (defaults in parentheses):

keytypemeaning
reg_weightRealactive-regularizer weight — native units for TV-style penalties (5e-16); fraction of initial data misfit for force_balance (0.1)
density_kg_m3Realtissue density (1000.0)
max_global_itersIntglobal iteration cap (20)
mesh_resolutionInthex-mesh strategy 1/2/3 (1)
linear_solverString"mumps" / "krylov" / "direct"; anything else → solver default (cached direct)
compute_backendStringgradient/zone device: "auto" / "metal" / "cuda" / "cpu" ("auto")
serialBoolforce 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:

julia
(giter::Int, objective::Float64, disp_error::Float64,
 converged::Bool, mean_shear_kpa::Float64)

mean_shear_kpa is the mean reconstructed shear-stiffness magnitude |μ| in kPa at that iteration (drives FORGE's mean-shear convergence sparkline). Exceptions thrown by the callback abort the solve.

Return value

(; real_shear, imag_shear, voxel_size, dims, stats):

  • real_shear, imag_shearArray{Float64,3}, storage/loss shear modulus (Pa) on the original image voxel grid. Voxels outside the reconstructed domain are NaN (deliberate "no reconstruction" sentinel — do not assume finite arrays; a 0.0 background would corrupt loss_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 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 by select_parallel_strategy.

  • Sentinel.AbstractLinearSolver subtyping + Sentinel.linear_solve / Sentinel.invalidate_cache for 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 .dat parser.

  • parse_inverse_runfile, raise_config — internal steps of load_inversion(".dat").

  • build_reg_config — the constructor's internal cross-spec validator.

  • SolveConfig, RegBuildContext, build_regularizer — setup internals behind setup_inverse_problem.

  • Zone drivers, batched solvers, gradient backends, and everything under src/distributed/ — reachable for power users via run_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.