-
Notifications
You must be signed in to change notification settings - Fork 25
Description
Context
After restructuring dMRIPrep to follow fMRIPrep's fit/transform architecture, this issue captures a comprehensive assessment of the current state and lays out a prioritized roadmap toward a functioning pipeline.
The CLI, config system, and argument parser are essentially complete. The workflow scaffolding (base.py, dwi/fit.py, dwi/base.py) is well-structured and fMRIPrep-aligned. However, several critical components are placeholder or disconnected, preventing an end-to-end run.
P0 — Blockers for a minimal working pipeline
1. SDC never applied during resampling
ResampleDWISeries (workflows/dwi/resampling.py) has a pass placeholder where fieldmap correction should be composed into the transform chain. The entire SDC estimation pipeline produces results that are never consumed during resampling.
Action: Use SDCFlows utilities to compose the fieldmap warp into the per-volume transform chain (motion × fieldmap × coreg), then resample in a single interpolation step. Implement Jacobian modulation.
2. NiFreeze interface API unvalidated
The interfaces in interfaces/nifreeze.py (NiFreezeEstimate, ExtractTransforms) assume an API (DWI.from_filename, Estimator, .motion_affines, .eddy_xfms) that was drafted speculatively.
Additionally, transforms3d is used in _write_motion_params but is not in the project dependencies.
Action: Validate against the actual nifreeze package and adapt. Wire FLIRT fallback (init_dwi_hmc_flirt_wf) as an interim alternative. Related: #181.
3. Workflow graph smoke test
No test verifies that init_dwi_fit_wf or init_dwi_wf can build a graph without errors. Also missing: __init__.py in workflows/dwi/tests/.
Action: Add a minimal test using mock_config() that constructs the workflow graph. Related: #182.
4. BIDSSourceFile references bold instead of dwi
interfaces/bids.py (line ~108): self.inputs.bids_info['bold'] should be 'dwi'.
P1 — Feature completeness
5. Standard-space resampling loop
dwi/base.py receives anat2std_xfm, std_t1w, std_mask from the template iterator but never creates a standard-space resampling workflow. --level full only produces T1w-space outputs, not volumetric standard-space outputs.
6. Transform format consistency
The non-BBR coregistration path outputs LTA-format transforms, but downstream consumers (nitransforms, ResampleDWISeries) expect ITK format. Need LTA→ITK conversion or consistent format throughout.
7. Disconnected reportlet wiring
reportlets_wf.inputnode.summary_reportandvalidation_reportare not connected indwi/base.py.- Coregistration
out_reportfrominit_dwi_reg_wfis generated but never datasunk.
P2 — Quality and interpretability
8. T2w-based coregistration
init_dwi_t2w_reg_wf exists in registration.py, and the config supports dwi2anat_init = 't2w', but the fit workflow never receives T2w data. The intent is set in base.py but never propagated.
9. Motion/quality confounds
Generate _desc-confounds_timeseries.tsv with framewise displacement (adapted for DWI), motion parameters, mean signal, and outlier flags.
10. QC reportlets
- SDC before/after comparison
- Coregistration overlay
- Motion parameter time-series plots
DiffusionSummaryexists inreports.pybut is never instantiated
11. HMC model auto-selection
Currently hardcodes model='DTI'. Should auto-select based on shell structure: 'average' for single-shell with few directions, 'DTI' for single-shell, 'DKI'/'GP' for multi-shell.
12. BIDS-URI provenance
BIDSURI interface exists in interfaces/bids.py but is never used. No Sources fields in derivative sidecar JSONs.
13. FLIRT fallback wiring
init_dwi_hmc_flirt_wf exists in hmc.py but has no selection logic to use it when NiFreeze is unavailable or --ignore eddy is set.
P3 — Longer-term vision
- Multi-run DWI merging — combine opposed-PE runs into a single corrected dataset (mentioned in code comments, not implemented)
- CIFTI DWI outputs — project to grayordinates for surface-based connectivity; anatomical CIFTI machinery is already wired from SMRIPrep
- Slice-level outlier detection — detect/replace corrupted slices, a common DWI artifact
- MP-PCA denoising — optional Marchenko-Pastur denoising before any interpolation
- Gibbs ringing correction — optional via DIPY or MRtrix3 (related: Gibbs ringing - estimation and correction workflow #179)
- Signal drift correction —
RescaleB0interface exists but isn't integrated - Integration tests & CI — end-to-end test with THP data; update stale Dockerfile (related: Build comprehensive integration and stress testing into dMRIPrep #182)
Suggested attack order
- Validate NiFreeze API (or wire FLIRT fallback) → HMC can execute
- Implement SDC in
ResampleDWISeries→ fieldmaps actually get applied - Workflow graph smoke test → safety net for everything else
- Fix trivial bugs (bold→dwi, missing
__init__.py, reportlet wiring) - Standard-space resampling loop →
--level fullworks properly - Confounds + QC reportlets → interpretable outputs
This gets to a minimal viable pipeline that can run --level minimal (steps 1–4) and produce corrected outputs in standard spaces (steps 5–6).
Priority matrix
| Priority | Item | Effort | Impact |
|---|---|---|---|
| P0 | ResampleDWISeries SDC placeholder |
Medium | Pipeline correctness |
| P0 | Validate NiFreeze interface API | Medium | Pipeline can execute |
| P0 | Workflow graph smoke test | Low | Prevents regressions |
| P0 | BIDSSourceFile bold→dwi |
Trivial | Correctness |
| P1 | Standard-space resampling loop | Medium | Feature completeness |
| P1 | Transform format consistency (LTA→ITK) | Low | Correctness |
| P1 | Disconnected reportlet wiring | Low | Clean execution |
| P2 | T2w coregistration wiring | Medium | Feature completeness |
| P2 | Confounds TSV generation | Medium | Downstream usability |
| P2 | QC reportlets | Medium | Interpretability |
| P2 | BIDS-URI provenance | Medium | Reproducibility |
| P3 | Multi-run merging | High | Advanced datasets |
| P3 | CIFTI DWI outputs | High | Connectivity analysis |
| P3 | Denoising / Gibbs | Medium | Signal quality |