DeepRelaxo
May 7, 2026 · View on GitHub
MRM 2025 | HuggingFace | deepMRI collection
This repository contains a PyTorch inference pipeline for the DeepRelaxo cascade: an estimator stage based on Transformer-MLP followed by a denoiser stage based on 3D-UNet.
Jump to: Highlights · Layout · Quick Start · DICOM → NIfTI conversion · Web App · Command-Line Interface · Run Demo Examples
Highlights
- NIfTI / MAT input — multiple 3D echoes or a single 4D volume (
.nii,.nii.gz,.matv5/v7.3 all supported). - DICOM → NIfTI converter — standalone
dicom_to_nifti.py(byte-identical with the copies in iQSM and iQSM+). One folder or many (--dicom_dir A B …); auto-classifies byImageType/ComplexImageComponent/ GE private tag(0043, 102f); writes a single NIfTI per modality (3D for single-echo, 4D for multi-echo) plus aparams.jsonready for--from_converted. Modality flags (--phase_dir,--mag_dir, …) are a rescue path for mis-tagged DICOMs. Mixed-modality folders are fine — DeepRelaxo only consumes the magnitude output. - Browser-based UI — collapsible sections, live progress, slice slider, shape verification (echo-to-echo and mask-vs-magnitudes), brain-mask preview alongside the R2* maps, per-run "equivalent CLI command" log entry, port auto-fallback (
7860 → 7861 → …), and SSH-aware launch (the auto-open browser step is skipped on remote hosts and a port-forward hint is printed instead). - Two outputs — Step 1 (
R2s_transformer_mlp.nii) is downloadable as soon as it's ready; Step 2 (R2s_deeprelaxo.nii) finalises afterwards.
Layout
app.py— Gradio web app for browser-based inference.run_deeprelaxo_pipeline.py— runs the estimator stage followed by the denoiser stage.run_estimator_stage.py— estimator-stage inference utilities.run_denoiser_stage.py— single-map denoiser inference utilities.dicom_to_nifti.py— standalone, self-contained DICOM → NIfTI converter. Byte-identical with the copies in iQSM and iQSM+; writes a single magnitude NIfTI (3D / 4D) plus aparams.jsonready for--from_converted.data_utils.py— NIfTI / MAT / DICOM loaders and shape utilities (the in-repo magnitude-only DICOM loader is whatrun_deeprelaxo_pipeline.py --dicom_diruses; for new workflows prefer the standalonedicom_to_nifti.py).transformer_mlp_model.pyandunet3d_model.py— model architectures.
Quick Start
1. Get the code
Option A — Git
git clone https://github.com/sunhongfu/DeepRelaxo.git
cd DeepRelaxo
Option B — Download ZIP
- Open the GitHub repository page.
- Click Code → Download ZIP.
- Unzip and open a terminal in the folder.
2. Install dependencies
A fresh virtual environment is the recommended way — it isolates DeepRelaxo's dependencies from anything else on your system and avoids version conflicts.
You need Python 3.10 or 3.11. Check your version:
python --version
If Python is not installed, download it from python.org. On Windows, tick Add Python to PATH during installation.
Create and activate a virtual environment:
macOS / Linux:
python -m venv venv
source venv/bin/activate
Windows:
python -m venv venv
venv\Scripts\activate
You should see (venv) in your prompt. Run this activation command each time you open a new terminal.
Install PyTorch. Go to pytorch.org/get-started/locally, select your OS and CUDA version, and copy the install command. For example:
CUDA 12.4 (recommended if you have an NVIDIA GPU):
pip install torch --index-url https://download.pytorch.org/whl/cu124
CPU only (slower, but works without a GPU):
pip install torch --index-url https://download.pytorch.org/whl/cpu
Install remaining dependencies. Pick one of the two options below depending on whether you want the browser-based web app:
-
Web app + Command-Line (recommended for most users):
pip install -r requirements-webapp.txtAdds Gradio and Matplotlib for the browser UI and slice previews.
-
Command-Line only (lighter install, fewer dependencies, no web stack):
pip install -r requirements.txtSkips Gradio and its ~18 transitive packages (FastAPI, Pydantic, Uvicorn, etc.). Recommended for headless servers, HPC clusters, or environments where Gradio's deps conflict with other tools.
Already have PyTorch installed? Click here to skip the venv setup.
If you have a working Python environment with PyTorch and prefer to reuse it, install one of the two requirements files above into that environment directly.
Note: this may upgrade or downgrade other packages in the environment (e.g. pydantic, typing-extensions) and can conflict with unrelated tools like TensorFlow. A clean venv avoids this. The Command-Line only install is much less likely to cause conflicts since it doesn't pull in Gradio's dependency chain.
3. Download checkpoints (and optionally demo data)
Large files (checkpoints and demo data) are excluded from git and hosted on Hugging Face: sunhongfu/DeepRelaxo.
Download checkpoints (~350 MB, required, one-time):
python run_deeprelaxo_pipeline.py --download-checkpoints
Optional — download demo data. If you'd like to try DeepRelaxo on a provided 5-echo GRE NIfTI dataset (TE = 4.9, 9.9, 14.8, 19.8, 24.7 ms) before adapting it to your own data, also run:
python run_deeprelaxo_pipeline.py --download-demo
This places sample magnitude echoes and a BET mask in demo/. See Run Demo Examples below for how to run it.
Manual download (optional). If the auto-download fails (e.g. behind a firewall), grab the files from the Hugging Face page above and place them as follows:
DeepRelaxo/
├── checkpoints/
│ ├── transformer_mlp_epoch_80.pth
│ └── unet3d_epoch_140.pth
├── demo/
│ ├── BET_mask.nii
│ ├── mag1.nii
│ ├── mag2.nii
│ ├── mag3.nii
│ ├── mag4.nii
│ ├── mag5.nii
│ └── params.json
└── ...
4. Run
Choose the web app (recommended) or the command-line interface.
DICOM → NIfTI conversion
If your data is a folder of raw DICOMs from a multi-echo GRE acquisition, convert it once with the standalone script before running DeepRelaxo. The script is byte-identical with the copies in iQSM and iQSM+ — independent of the downstream pipeline. Pick whichever repo's copy is closest at hand.
Two modes
Normal path — --dicom_dir DIR [DIR …] · auto-classifies by DICOM ImageType, ComplexImageComponent, and the GE private tag (0043, 102f). Use this whenever your tags are reliable. DeepRelaxo only needs magnitude, so passing extra modalities is harmless — they're written to disk but not consumed:
# Single mixed folder of DICOMs (any extension or none — .dcm, .ima, .dicom):
python dicom_to_nifti.py --dicom_dir /path/to/dicoms
# Multiple folders walked together (e.g. magnitude + phase in separate dirs):
python dicom_to_nifti.py --dicom_dir /path/to/mag /path/to/phase
# Specify the output folder (default: ./dicom_converted):
python dicom_to_nifti.py --dicom_dir /path/to/dicoms --out_dir ./my_subject_converted
Rescue path — --mag_dir · for when magnitude DICOMs are mis-tagged (e.g. ImageType = ORIGINAL/PRIMARY/OTHER and --dicom_dir would route them to the wrong bucket). The script trusts the caller and force-places every file into the magnitude bucket:
python dicom_to_nifti.py --mag_dir /path/to/magnitude_dicoms
The --phase_dir, --real_dir, --imag_dir rescue flags exist too but produce phase / real / imaginary NIfTIs that DeepRelaxo doesn't consume — if you don't have any magnitude DICOMs at all, you'll have to derive magnitude yourself before running DeepRelaxo. The two modes can't be mixed.
After conversion the script writes (names depend on echo count):
converted/
├── dcm_converted_magnitude[_4d].nii.gz # 3D for single-echo, 4D for multi-echo
├── dcm_converted_phase[_4d].nii.gz # written if phase was present (DeepRelaxo ignores it)
└── params.json
…and prints a copy-paste-friendly summary:
─── Acquisition values (paste these into the web app) ───
Echo Times (ms) : 4.9, 9.9, 14.8, 19.8, 24.7
Voxel size (mm) : 1 1 1
B0 (Tesla) : 3.0
─────────────────────────────────────────────────────────
params.json carries machine-readable values (te_ms, voxel_size_mm, b0_T, b0_direction) and copy-paste strings (te_ms_string, voxel_size_string, b0_direction_string) formatted exactly the way the web app's input field expects them. Open the JSON, copy the relevant string, paste into the form. Or skip the form and use --from_converted (auto-fills everything from the same JSON):
# CLI — auto-loads TEs and the magnitude NIfTI path from params.json:
python run_deeprelaxo_pipeline.py --from_converted ./dicom_converted \
--mask BET_mask.nii
# Web app — upload dcm_converted_magnitude[_4d].nii.gz to "MRI Magnitudes"
# (4D files are accepted as multi-echo), paste te_ms_string from
# params.json into the Echo Times field:
python app.py
--out_diris overwritten in place on each run. A single consolidatedparams.jsonis written. Ifparams.jsonor anydcm_converted_*.nii(.gz)already exists, the script lists them and prints a clear warning before overwriting. Use a fresh--out_dirper subject / acquisition.
Why isn't this in the web app? Browsers don't handle thousand-file folder uploads well: tempfile creation per file hits the OS open-file limit (
OSError: Too many open files), and the "Upload N files to this site?" prompt makes some users worry their data is being uploaded to a remote server. Running the converter locally avoids both — and DICOM → NIfTI is a one-time step, so re-running the pipeline after that is fast.
Web App
python app.py
The app picks port 7860 by default; if it's busy, it falls back automatically (7861, 7862, …). Your default browser opens automatically at the dark-themed URL once the server is ready (no flash of light theme).
Usage walk-through
The page is organised top-to-bottom; each section is a collapsible accordion.
1. MRI Magnitudes
Click Add NIfTI / MAT Magnitudes and pick:
- multiple 3D files (one per echo) —
.nii,.nii.gz, or.mat; or - a single 4D volume of shape
(X, Y, Z, n_echoes).
Files with unsupported extensions are dropped with a Gradio warning toast. You can add files in batches.
.mat files are accepted in both v5 (default save) and v7.3 (save -v7.3) formats; each .mat file must contain exactly one numeric array.
Have raw DICOMs? The web app deliberately doesn't accept whole DICOM folders — uploading thousands of files through a browser is unreliable (file-handle exhaustion, mid-transfer drops) and the privacy prompts confuse users. Convert them locally with
dicom_to_nifti.pyinstead, then upload the resulting NIfTI files here.
2. Processing Order
Lists every magnitude file that will be fed to the pipeline (sorted in natural numeric order: mag1, mag2, …, mag10). Below the list, a one-line shape summary tells you whether all files share the same volume dimensions — and if not, lists each per-file shape so you can spot the outlier.
- Click ✕ next to any file to remove it (≥2 files only).
- Click ✕ Remove all magnitudes to wipe the list.
3. Echo Times (ms)
A single textbox accepts two equivalent formats:
- Comma-separated values — one per echo, irregular spacings allowed:
2.4, 3.6, 9.2, 20.8 - Compact
first_TE : spacing : count— uniform spacing only:4.9 : 5 : 5expands to4.9, 9.9, 14.8, 19.8, 24.7
4. Brain Mask (optional)
Click Select Brain Mask to provide a BET (or any binary) mask. Supported: .nii, .nii.gz, .mat (v5 or v7.3).
After upload, the field shows: Loaded: BET_mask.nii · Shape: 192 × 256 × 176 · dtype: uint8 · ✓ matches magnitudes. If the mask shape doesn't match the spatial dims of your magnitudes, you get a clear warning so you can fix it before running.
Click ✕ Remove Brain Mask to clear it. Without a mask, all voxels are processed — significantly slower than processing only the masked brain region.
5. Hyper-parameters (collapsed by default)
Voxel Batch Size — defaults to 50,000. Reduce if you run out of GPU memory.
6. Run Pipeline
Hit the green Run Pipeline button. Three sections appear in sequence:
- Log — streaming console output, including a RUN CONFIGURATION block that prints the equivalent command-line invocation so you can reproduce the run from a terminal.
- Results —
R2s_transformer_mlp.nii(Step 1) downloadable as soon as it's ready, thenR2s_deeprelaxo.nii(Step 2) once the denoiser finishes. - Visualisation — middle-slice grayscale preview of both maps, with a Z-slice slider (Prev / Next buttons or drag) to scrub through the volume. Display window (
R2*min / max in s⁻¹) is editable. If you supplied a brain mask, it's previewed below the R2* maps (sharing the same slice slider) so you can spot orientation mismatches at a glance.
GPU memory is released between runs, so you can upload a new dataset and re-run without restarting the page.
Command-Line Interface
The pipeline can also be driven from the terminal using a YAML config file or explicit arguments.
Config file
python run_deeprelaxo_pipeline.py --config config.yaml
Example config.yaml:
data_dir: Data/your_subject
echoes:
- file: mag_echo_01.nii
te_ms: 4.9
- file: mag_echo_02.nii
te_ms: 9.9
- file: mag_echo_03.nii
te_ms: 14.8
mask: BET_mask.nii
transformer_out: transformer_outputs
deeprelaxo_out: deeprelaxo_outputs
transformer_batch_size: 50000
For a single 4D NIfTI:
data_dir: Data/your_subject
echo_4d: magnitudes_4d.nii.gz
te_ms: [4.9, 9.9, 14.8]
mask: BET_mask.nii
Direct Command-Line
From a folder produced by the standalone dicom_to_nifti.py — TE values and the magnitude NIfTI path are read from params.json:
python run_deeprelaxo_pipeline.py \
--from_converted Data/your_subject/dicom_converted \
--mask BET_mask.nii
--from_converted reads dcm_converted_magnitude[_4d].nii.gz (3D for single-echo, 4D for multi-echo) and the TE list from params.json. This is the recommended path.
DICOM folder, one-shot (skips the standalone-conversion step — convenient if you don't plan to re-run on the same data):
python run_deeprelaxo_pipeline.py \
--dicom_dir Data/your_subject_dicoms \
--mask BET_mask.nii
The folder is walked recursively, magnitude images are filtered, grouped by EchoTime, sorted by ImagePositionPatient, and saved as one NIfTI per echo (dcm_converted_to_nii_e1.nii, dcm_converted_to_nii_e2.nii, …) inside <transformer_out_parent>/dicom_converted_nii/. TE values come from headers — pass --te_ms only to override. This is the legacy in-repo magnitude-only loader; for repeat runs over the same dataset, prefer the standalone dicom_to_nifti.py + --from_converted (output schema is unified and params.json carries copy-paste-ready strings).
Multiple 3D NIfTI echoes:
python run_deeprelaxo_pipeline.py \
--data_dir Data/your_subject \
--echo_files mag1.nii mag2.nii mag3.nii \
--te_ms 4.9 9.9 14.8 \
--mask BET_mask.nii
Single 4D NIfTI:
python run_deeprelaxo_pipeline.py \
--data_dir Data/your_subject \
--echo_4d magnitudes_4d.nii.gz \
--te_ms 4.9 9.9 14.8 19.8 24.7 \
--mask BET_mask.nii
MATLAB inputs (one file per echo):
python run_deeprelaxo_pipeline.py \
--data_dir Data/your_subject \
--echo_files mag1.mat mag2.mat mag3.mat \
--te_ms 4.9 9.9 14.8 \
--mask BET_mask.nii
MATLAB 4D:
python run_deeprelaxo_pipeline.py \
--data_dir Data/your_subject \
--echo_4d magnitudes_4d.mat \
--te_ms 4.9 9.9 14.8 19.8 24.7 \
--mask BET_mask.nii
.mat inputs (magnitudes or mask) must contain a single numeric array per file. If a .mat file contains multiple arrays, re-save it with only the array you want. The same applies to .mat masks.
Config notes
data_dir,transformer_out, anddeeprelaxo_outare resolved relative to the config file.- Echo file and mask paths are resolved relative to
data_dir. Absolute paths are kept verbatim (so you can mix files from different folders). --data_diris optional in direct CLI mode — defaults to the current working directory if omitted.- If
maskis omitted, an all-ones mask is used. - Default
transformer_batch_sizeis50000; reduce if GPU memory is limited. - Checkpoints are loaded from
checkpoints/transformer_mlp_epoch_80.pthandcheckpoints/unet3d_epoch_140.pth.
Run Demo Examples
Once you've downloaded the demo data (see step 3 of the Quick Start), the easiest way to verify your install is to run the demo from the command line. The demo is a 5-echo GRE acquisition with TE = 4.9, 9.9, 14.8, 19.8, 24.7 ms.
Option 1 — Command-line with direct arguments
python run_deeprelaxo_pipeline.py \
--data_dir demo \
--echo_files mag1.nii mag2.nii mag3.nii mag4.nii mag5.nii \
--te_ms 4.9 9.9 14.8 19.8 24.7 \
--mask BET_mask.nii
Option 2 — Command-line with a YAML config
Save the following as demo_config.yaml:
data_dir: demo
echoes:
- file: mag1.nii
te_ms: 4.9
- file: mag2.nii
te_ms: 9.9
- file: mag3.nii
te_ms: 14.8
- file: mag4.nii
te_ms: 19.8
- file: mag5.nii
te_ms: 24.7
mask: BET_mask.nii
Then run:
python run_deeprelaxo_pipeline.py --config demo_config.yaml
Option 3 — Run the demo through the web app
Launch the web app:
python app.py
Under MRI Magnitudes, click Add NIfTI / MAT Magnitudes and pick all five demo/mag*.nii files. In Echo Times, paste 4.9, 9.9, 14.8, 19.8, 24.7 (or the compact form 4.9 : 5 : 5). In Brain Mask, click Select Brain Mask and pick demo/BET_mask.nii. Hit Run Pipeline.
All three options produce the same outputs: a Step 1 R2* map (R2s_transformer_mlp.nii) and a final denoised R2* map (R2s_deeprelaxo.nii).