BIDS Statistical Models implementation.
This crate implements the BIDS-StatsModels
specification for defining reproducible neuroimaging analysis pipelines as
declarative JSON documents. It corresponds to PyBIDS' bids.modeling module.
Overview
A BIDS Stats Model defines a directed acyclic graph (DAG) of analysis nodes, each operating at a specific level of the BIDS hierarchy (run, session, subject, dataset). Data flows from lower levels to higher levels through edges, with contrasts propagating upward.
Components
-
[
StatsModelsGraph] — The top-level model graph loaded from a JSON file. Validates structure, wires edges between nodes, and executes the full analysis pipeline. Can export to Graphviz DOT format. -
[
StatsModelsNode] — A single analysis node with a statistical model specification, variable transformations, contrasts, and dummy contrasts. Nodes group data by entity values and produce [StatsModelsNodeOutput]s. -
[
TransformSpec] and [apply_transformations()] — Thepybids-transforms-v1transformer implementing Rename, Copy, Factor, Scale, Threshold, Select, Delete, Replace, Split, Concatenate, Orthogonalize, Lag, and more. -
[
HrfModel], [spm_hrf()], [glover_hrf()] — Hemodynamic response function kernels (SPM and Glover canonical forms with optional time and dispersion derivatives). Uses a pure-Rustgammalnimplementation matching SciPy's cephes to machine epsilon. -
[
auto_model()] — Automatically generates a BIDS Stats Model JSON for each task in a dataset, with Factor(trial_type) at the run level and pass-through nodes at higher levels. -
[
GlmSpec], [MetaAnalysisSpec] — Statistical model specifications with design matrix construction, VIF computation, and formatted output.
Example
use bids_modeling::StatsModelsGraph;
let mut graph = StatsModelsGraph::from_file(
std::path::Path::new("model-default_smdl.json")
).unwrap();
graph.validate().unwrap();
println!("DOT graph:\n{}", graph.write_graph());
// Execute the model
let outputs = graph.run();
for output in &outputs {
println!("Node: {}, Contrasts: {}", output.node_name, output.contrasts.len());
}