WBFR : a wavelet based approach to background field removal QSM is a reproducible computational method for the extraction of tissue magnetization field maps within the spinal chord developed as part of the 2026 of Brainhack School.
WBFR aims to offer the field of quantitative susceptibility mapping an alternative to the more established background field removal algorithms. Broadly speaking, the traditional BFR algorithms (PDF, LBV, and the SHARP family of algorithms) are all based on the assumption of a harmonic background field within the cord ROI.
WBFR is truly novel in the sense that it does not make that assumption but leverages the multi-scale analysis capabilities of the discrete wavelet transform.
Magnetic susceptibility is a property of materials that describes their reaction to being submerged in a magnetic field. The magnetic susceptibility distribution within some volume of tissue can reveal important information about its chemical composition. Myelin — a fatty material that surrounds and protects neurons — has negative magnetic susceptibility, whereas iron has positive magnetic susceptibility. Mapping the concentrations of myelin and iron within the spinal cord and the brain has proven immensely helpful in the diagnosis and prognosis of some degenerative diseases — most importantly, multiple sclerosis (MS).
QSM is a method of processing MRI data in a way that creates a map of the magnetic susceptibility distribution within a given region of interest (ROI). The steps below describe how QSM takes the phase and magnitude data produced by MRI scanners to output a susceptibility field map within the ROI (a local field map or chi-map).
Acquire phase and magnitude data
BFR is arguably the most important step in the QSM pipeline. It is where most of the information about the local field is either gained (by the successful removal of background artefacts) or lost.
A classical result of electromagnetism tells us that for any bounded domain
with
For any point
The reasoning behind using the SVM for BFR is mathematically sound, but it clashes with the practical, physical limitations of MRI imagery.
Just as the smallest unit of precision of a 2D image is the pixel, the smallest unit of precision of an MRI is the voxel (volumetric pixel) — a cube of side length approx.
As mentioned in our statement of the SVM, we need
The easiest, most drastic way of dealing with what happens in the boundary region is simply to erode the mask — removing the boundary region from the ROI entirely.
For a large ROI such as the brain, eroding the mask can be done without sacrificing too much valuable information. The cord, on the other hand, is
What tells most classical BFR algorithms from one another is the assumptions made on the behavior of the background within the danger zone that is the boundary region.
| Assumptions | Acronym | Algorithms |
|---|---|---|
| NO magnetic field Sources on the boundary of the ROI | NOS | SHARP (V-SHARP) |
| Assumption of No Harmonic internal and boundary i.e. that the value of the background field in the boundary region is equal to that of the total field. | NOHA | LBV |
| Minimization of an Objective function Involving a Norm: Takes a family of approximations for the background field and selects the one with the smallest |
MOIN |
Research at Neuropoly has concluded that PDF is the best-performing algorithm for BFR of the spinal cord.
Another difference between QSM of the brain and QSM of the spinal cord is the greater diversity of sources for the background field of the cord. The lungs, the trachea, tissue interface between the cord and CSF, the vertebrae all create contributions that vary with sometimes indiscernible frequencies.
To differentiate between low frequency contributions like the spine, intermediate frequency like the trachea, and high frequency like tissue interface we look toward the wavelet transform. A mathematical tool that decomposes signals into different spatial and frequency scales.
A wavelet takes the form
An image can be decomposed into an infinite sum of terms of the form
Here an image of a man holding a camera is decomposed using the Discrete Wavelet-Transform (DWT). The output of the transform is always of the form
To mesure the effectiveness of the wavelet transform as a means of removing background field in the spinal cord, we need a total fieldmap on which to apply the DWT and local field that we know is accurate, a ground truth, with which we'll compare the output of the transform.
An accurate tissue field is impossible to guarantee in in-vivo data. That is why we rely on the whole-body phantom : a numerical "crash-test dummy" for MRI methods developed by the Neuropoly lab. In a nutshell, a 3D model of the human body was made along with a map of all the magnetic properties of tissue relevant for MRI. The two put together can be used to accurately simulate MRI acquisition.
Using the tissue-to-MR module in Neuropoly's shimming toolbox, and passing the whole-body phantom as input we create maps for the main MRI properties of tissue
If we isolate the spinal cord by applying a mask that only preserves the white matter and grey matter of the phantom and apply the steps to create the total field map but to this restricted region of the phantom, we get our local field ground truth.
STEP 0 (Setup): Divide the local field into slices along the $z-$axis. Choose a wavelet and a level of decomposition. For a fixed level
Below an example with
Initialize the list candidate_bands to be the entire set of
STEP 1 : Select a candidate band out of the candidate_bands that were not tested.
STEP 2 : Compute the inverse DWT using trial_bands = selected_bands + candidate.
STEP 3 : Compute the quality loss function on this trial image.
STEP 4 : If trial_score < baseline : move the candidate from the candidate_bands to the selected bands. Set baseline = trial score. else : move candidate from candidate_bands to tested_bands. Repeat steps 1 through 4 until there is no noticeable improvement in the baseline score.
Repeating this optimization loop for all 106 discrete wavelets available in the PyWavelets library and every decomposition level compatible with our image size (between 2 and 5 depending on the choice of wavelet) proved to be too computationally demanding for a single desktop computer. That's we ran a multithreaded optimizer on the Rorqual HPC cluster provided by Alliance Canada. Here is an anonymized version the sbatch-compatible script that was used to run our optimizer on Rorqual :
#!/bin/bash
#SBATCH --account=[grp-name]
#SBATCH --nodes=1
#SBATCH --ntasks-per-node=1
#SBATCH --cpus-per-task=16
#SBATCH --mem-per-cpu=4000M
#SBATCH --time=02:00:00
#SBATCH --job-name=wvt_experiments_opt
module load python/3.11 nibabel/5.2.0 scipy-stack
source ~/links/projects/grp-name/username/wvt_experiments/env/bin/activate
python ~/links/projects/grp-name/username/wvt_experiments/src/wavelet_band_selector_gt_parallel.py
submit.shOur choice of optimization loop is by no means efficient, nor is its solution guaranteed to be optimal, but similar greedy algorithms have proven to be useful heuristics in a number of real-world setting. We thought it would be a good place to start, and it did lead to some interesting results.
TLDR : It works wonderfully, and I have no earthly idea why !
The spine is divided into four regions: cervical, thoracic, lumbar and sacral. Slices of vertebrae C3, T2, and L1 provide a fair sample of the diversity of background field sources present in the spinal cord.
The portion of the cord located in the cervical spine experiences background field contributions from the trachea and the lungs, the thoracic portion experiences contributions from the lungs and from the geometry of the spine, the lumbar portion mainly experiences contributions from the geometry of the spine.
The cord is composed of white matter and grey matter. Within a slice of cord, we expect to see white matter surrounding the characteristic "grey-matter butterfly".
This is the region where the expect the greatest amount of perturbation, as it is close to the edge of our mask. Notice that while the background field isn't entirely removed in the WBFR result, the image has considerably more contrast than the corresponding slice in the PDF output.
We've struck gold ! WBFR preserves the most relevant structures of the cord —namely, the grey-matter butterfly —with again, more contrast than PDF.
We're beginning to notice a pattern here : Although the background isn't entirely removed, WBFR preserves contrast and structure. It also preserves more detail around the boundary of the cord than PDF does.
Using three standard metrics of image processing — the fields of compression and denoising in particular — we try to quantity the differences between the PDF output and that of WBFR. Mean-Squared-Error (MSE)
Correlation
Where
Structural-Similarity Index Measure (SSIM)
Where
It is quite surprising to find that WBFR doesn't perform particularly well in any of the standard metrics.

And yet, a qualitative analysis of WBFR by Neuropoly experts indicates that it keeps more of the clinically relevant details. It seems WBFR has a structure preserving property that we haven't been able to quantify. This warrants further investigation - which is, unfortunately, outside of the scope of this project.
- This repo follows the project structure guidelines set in The Good Data-science Handbook
- A virtual environment wvt_env_2 can be used to manage dependencies.
- A copy of the whole-body phantom can acquired by requesting access to the Neuropoly through osf
- Processing of the whole-body phantom was done using the open software in Neuropoly's Spinal-Cord Toolbox.
Run WBFR on one sample subject.
- Install dependencies
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt- Run a minimal example (subject 02)
mkdir -p output
PYTHONPATH=src python - <<'PY'
import nibabel as nib
from dwt_utils import load_nifti_as_array, dwt_bfr_volume
field_path = "data/sub-02/sub-02_desc-b0_fieldmap.nii.gz"
mask_path = "data/sub-02/sub-02_desc-SC_mask.nii.gz"
out_path = "output/sub-02_B_loc_dwt_quickstart.nii.gz"
field = load_nifti_as_array(field_path)
mask = load_nifti_as_array(mask_path) > 0
affine = nib.load(field_path).affine
B_loc = dwt_bfr_volume(
field,
mask,
wavelet="rbio1.3",
level=3,
keep_detail_levels=(3, 2),
sig_ext_mode="zero",
)
nib.save(nib.Nifti1Image(B_loc, affine=affine), out_path)
print("Saved:", out_path)
PY- Expected Result
A local-field estimate is saved at output/sub-02_B_loc_dwt_quickstart.nii.gz.
-
Lee, G. R., Gommers, R., Waselewski, F., Wohlfahrt, K., & O'Leary, A. (2019). PyWavelets: A Python package for wavelet analysis. Journal of Open Source Software, 4(36), 1237. https://doi.org/10.21105/joss.01237
-
van der Walt, S., Schönberger, J. L., Nunez-Iglesias, J., Boulogne, F., Warner, J. D., Yager, N., Gouillart, E., Yu, T., & the scikit-image contributors (2014). scikit-image: image processing in Python. PeerJ, 2, e453. https://doi.org/10.7717/peerj.453
-
De Leener, B., Lévy, S., Dupont, S. M., Fonov, V. S., Stikov, N., Collins, D. L., Callot, V., & Cohen-Adad, J. (2017). SCT: Spinal Cord Toolbox, an open-source software for processing spinal cord MRI data. NeuroImage, 145, 24–43. https://doi.org/10.1016/j.neuroimage.2016.10.009
-
Bollmann, S., Rasmussen, K. G. B., Kristensen, M., Blendal, R. G., Østergaard, L. R., Plocharski, M., O'Brien, K., Langkammer, C., Janke, A., & Barth, M. (2017). DeepMRI: quantitative susceptibility mapping using deep learning. NMR in Biomedicine. https://doi.org/10.1002/nbm.3604
-
Harris, C. R., Millman, K. J., van der Walt, S. J., et al. (2020). Array programming with NumPy. Nature, 585, 357–362. https://doi.org/10.1038/s41586-020-2649-2
-
Hunter, J. D. (2007). Matplotlib: A 2D graphics environment. Computing in Science & Engineering, 9(3), 90–95. https://doi.org/10.1109/MCSE.2007.55
- This project falls under the GNU licence.

