Surface-normal-driven detection of u-fiber-compatible fixels in superficial white matter, real-PTT u-fiber streamline tracking, sulcal-fundus tracing, and sheet detection — all on an ODX discrete fixel image.
Given paired wm.surf.gii / pial.surf.gii cortical surfaces and an ODX,
ufixels walks inward along each cortical normal voxel by voxel and asks:
is there a fixel oriented roughly tangent to the cortex? It then traces a
PTT trajectory from each candidate, gates the result by u-fiber-shaped
criteria, WM-crops it, and writes the surviving trajectories as a
tractogram. A downstream chain then fits a parabola/triangle to each
streamline, traces the sulcal-fundus spine along the apex field, collapses
parallel depth-slice spines into one scaffold per sulcal fundus, and
flood-assigns every streamline into a coherent sheet label.
ufixels also includes a surface-native sheet detector — it partitions
the cortical mesh into U-fiber sheets directly from gyral geometry, with no
streamlines or fundi. It is an independent track.
ufixels select_u_streamlines trace_apex_fundi assign_sheets
───────────────────────── ─────────────────────── ────────────────────── ──────────────────────
Phase 1 tangent fixel scale-invariant U gate per-streamline parabola QuickBundles on the
selection (bow-ratio + depth) fit → apex + triangle fundus polylines —
Phase 2 PTT trace + the L/D U-shape filter plane-normal field. collapses depth-
seven trajectory (lit-standard Real PTT on this parallel fundi into
gates 1.01 ≤ L/D ≤ 6). synthetic apex fixel ONE scaffold per
--crop-to-wm: paired optional parabola fit field with density- sulcal fundus.
white/pial signed WM crop gated termination. scaffold-seeded
+ endpoint + medial-wall orientation-weighted
gates label flood — every
│ │ │ triangle gets one
▼ ▼ ▼ sheet by consensus.
streamlines.trx u_selected.trx fundi.trx │
+ ODX DPFs ▼
sheets.trx +
scaffolds.trx
(color-matched
sheet_NNNN groups)
+ curvature_report — single-shot diagnostic: per-streamline min radius of
curvature, total turning angle, "still bending at termination" signature.
A diagnostic, not part of the production chain.
ufixels is the only stage that touches anatomy (surfaces, the ODX QA
field). Everything downstream is pure geometry on streamline TRX inputs —
each layer is independently re-runnable, so shape / fundus / sheet
parameters can be tuned without re-paying the multi-hour PTT pass.
A separate track works directly on the cortical mesh — no streamlines.
detect_surface_sheets partitions the white-matter surface into U-fiber
sheets from gyral-crown geometry; wm_envelope builds the crown-depth
signal it relies on (or you supply a FreeSurfer sulc).
wm.surf.gii / pial.surf.gii ┐
ODX ┼─▶ detect_surface_sheets ─▶ colored sheet slabs
?h.sulc.shape.gii (optional)┘ + flow lines
+ crown ridges
wm.surf.gii ──────────────────▶ wm_envelope ───────────▶ crown-depth surface
This track is independent of the four-binary volume-PTT chain above — it
needs only the surfaces and the ODX. Run detect_surface_sheets --help for
the full set of tunables.
ufixels
- Per hemisphere
*.{first_voxel_diff,compatible_depth,end_condition}.shape.gii— per-vertex maps from the Phase 1 inward walk. - With
--append-dpfs-to-odx <ODX>: the input ODX copied in place with per-fixel DPFs attached for trxviz fixel visualisation —ufixel_selected(Phase 1),ufixel_selected_connectivity(Phase 2 trajectory_pass ∧ hit_count ≥ K),ufixel_hit_count(peer-vote weighting). - With
--streamlines <TRX>(alias--debug-trx): the WM-cropped/gated primary streamline derivative. Each streamline carries aufixel_hit_count_meanf32DPS (path-averaged peer-consensus score).
select_u_streamlines: TRX of shape-passing (optionally parabola-fitted)
streamlines, with the over-wrap-spiral tail rejected by the L/D filter.
Per-streamline DPS preserved.
trace_apex_fundi: TRX of sulcal-fundus polylines, one sheet_NNNN
group per fundus (numbering is unstable across runs; use assign_sheets for
the final sheet ids).
assign_sheets: two TRX files —
--out: input streamlines regrouped intosheet_NNNN;--bundles-out(optional): the surviving scaffold polylines under the samesheet_NNNNids → load both in TRXViz with Color by Group and scaffolds inherit their sheet's colour.
detect_surface_sheets: per hemisphere — a colored per-sheet slab
GIFTI, a per-face stick TRX, the SWM depth-stack meshes, and (optionally)
flow-line and crown-ridge TRX.
wm_envelope: the smoothed depth-reference envelope surface and the WM
surface recolored by signed crown-depth.
git clone https://github.com/PennLINC/ufixels && cd ufixels
cargo build --release # binaries land in target/release/All dependencies (odx-rs, gifti-rs, odx-tractography, trx-rs) resolve from public git tags — no local checkouts or path overrides required. Rust ≥ 1.85.
ufixels needs an ODX fixel image and four GIFTI surfaces
({lh,rh} × {white,pial}), all co-registered in the same RAS+mm space.
Producing them from FreeSurfer + processed dMRI (surface conversion,
registration into the dMRI/ODX space, ODX generation) is documented in
PREP.md. Validate the overlay in TRXViz before running —
silent coordinate misalignment is the most common failure.
The tuned parameters are the binary defaults, so the minimal invocation is short:
# 1. anatomy-aware: detect, trace, crop, gate → primary TRX + ODX DPFs
ufixels \
--lh-wm acpc_lh.white.surf.gii --lh-pial acpc_lh.pial.surf.gii \
--rh-wm acpc_rh.white.surf.gii --rh-pial acpc_rh.pial.surf.gii \
--odx subject.odx \
--output-prefix subject_ \
--append-dpfs-to-odx subject_with-ufixels.odx \
--connectivity-filter --crop-to-wm \
--streamlines subject_ufixels.trx
# 2. geometric U-shape + L/D filter (drops under-wrap straightness AND over-wrap spirals)
select_u_streamlines --trx subject_ufixels.trx --out subject_u_selected.trx
# 3. fundus tracing: real PTT on the apex field, density-gated termination
trace_apex_fundi --trx subject_u_selected.trx --out subject_fundi.trx
# 4. sheet assignment: QB-collapse fundi → scaffolds; orientation-flood streamlines
assign_sheets \
--fundi subject_fundi.trx --trx subject_u_selected.trx \
--out subject_sheets.trx --bundles-out subject_scaffolds.trx--bundle-mdf-mm (default 6) on assign_sheets is the anatomical-scale
knob — sweep 4 / 6 / 8 and judge scaffold-vs-sulcus correspondence in TRXViz
(lower → finer/more sheets, higher → coarser/fewer).
| Stage | Flag | Default | Meaning |
|---|---|---|---|
| Phase 1 | --compatible-angle / --max-angle-diff |
90 / 20 | target tangent angle and tolerance (deg) |
| Phase 1 | --max-depth |
20 | inward-walk cap (mm) |
| Phase 2 PTT | --ptt-k-max |
1.5 | curvature ceiling (R_min ≈ 0.67 mm) |
| Phase 2 PTT | --ptt-probe-mm |
1.0 | probe arc length (mm); short for tight bends |
| Phase 2 PTT | --ptt-step-mm |
0.5 | integration step (mm); must be ≪ bend radius |
| Phase 2 PTT | --ptt-n-k-samples |
15 | curvature grid per axis (total = n²) |
| Phase 2 PTT | --ptt-seeds-per-fixel |
8 | Halton sub-voxel multi-seed |
| Phase 2 length | --max-trace-length-mm |
25 | per-direction trace cap (50 mm total raw) |
| Phase 2 length | --max-total-length-mm |
50 | post-filter total length cap (must match raw cap) |
| Phase 2 gates | --endpoint-max-mm |
3 | raw-trajectory endpoint → cortex |
| Phase 2 gates | --min-arc-deviation-mm |
2 | trajectory must bow this far from chord |
| Phase 2 gates | --max-path-depth-mm |
8 | no point deeper than this from cortex |
| Phase 2 gates | --no-end-otsu-factor |
2.0 | flag densest-WM voxels as forbidden endpoints (DSI-Studio convention × 2) |
| Crop / gate | --crop-to-wm |
off | paired white/pial signed WM crop + endpoint + medial-wall gates |
| Crop / gate | --wm-margin-mm / --wm-min-kept-vertices |
0.5 / 4 | WM-containment margin; min kept vertices |
| Crop / gate | --wm-endpoint-max-mm |
3 | cropped endpoint → non-medial white surface |
| Crop / gate | --medial-wall-buffer-mm |
3 | reject if a cropped endpoint is within this of the medial wall |
| Geometry | --min-bow-ratio |
0.20 | scale-invariant U gate (sagitta/chord); rejects straight streamlines |
| Geometry | --min-depth-mm |
0.5 | absolute apex-sag noise floor |
| Geometry | --max-l-over-d / --min-l-over-d |
6.0 / 1.01 | UFA-standard U-shape filter (rejects spirals + straight runs) |
| Geometry | --fit-parabolas / --samples |
off / 64 | replace survivors with the fitted parabola |
| Fundus | --support-rel-floor (trace_apex_fundi) |
0.7 | density-gated stop: fraction of seed-ridge support |
| Fundus | --max-fundus-mm (trace_apex_fundi) |
50 | total fundus length cap (rf07 regime) |
| Sheet | --bundle-mdf-mm (assign_sheets) |
6.0 | QuickBundles MDF for collapsing parallel-depth fundi into scaffolds (anatomical-scale knob) |
| Sheet | --seed-radius-mm / --seed-cos |
2.0 / 0.85 | scaffold-seeding distance + orientation gates |
| Sheet | --flood-radius-mm / --flood-iters |
2.5 / 10 | label-propagation kNN radius and iterations |
| Sheet | --orient-power |
4 | exponent on |n·n'| in the consensus vote weight |
The Phase 2 trace defaults to a deterministic curvature grid. Additional
curvature-sampling strategies are available behind CLI switches:
--ptt-stochastic (support-weighted CDF sampler), --ptt-yeh +
--ptt-yeh-angle-deg (deterministic nearest-peak walk with a per-step
WM-shell limiter), --ptt-probabilistic + --ptt-prob-angle-deg
(bounded-cone amplitude sampling), and --ptt-probe-radius-mm /
--ptt-probe-count (fanned probe).
The four input GIFTI surfaces and the ODX must already be in the same
RAS+mm coordinate system (typically subject ACPC space or a native space).
The streamline TRX inherits the ODX's voxel_to_rasmm/dims, and
its points are RAS+mm, so it overlays the ODX and surfaces directly.
For per-binary options and tunables, run any tool with --help. Input
preparation (FreeSurfer surfaces → registered GIFTI, ODX generation) is in
PREP.md.
Dual-licensed under MIT or Apache-2.0 at your option.