Skip to content

Commit

Permalink
Merge pull request #20 from NordicMRspine/setup
Browse files Browse the repository at this point in the history
Unit test
  • Loading branch information
alexjaffray authored Aug 31, 2023
2 parents 485f306 + 821b361 commit 49c4114
Show file tree
Hide file tree
Showing 27 changed files with 897 additions and 198 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
fail-fast: false
matrix:
version:
- '1.6'
- '1.7'
- '1.8'
- 'nightly'
os:
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
*.jl.mem
Manifest.toml
.vscode
.DS_Store
.DS_Store
docs/build/*
14 changes: 8 additions & 6 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,23 @@ authors = ["Laura Beghini"]
version = "0.1.0"

[deps]
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
Coverage = "a2441757-f6aa-5fb2-8edb-039e3f45d037"
DSP = "717857b8-e6f2-59f4-9121-6e50c889abd2"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
DataInterpolations = "82cc6244-b520-54b8-b5a6-8a565e85f1d0"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549"
ImageUtils = "8ad4436d-4835-5a14-8bce-3ae014d2950b"
Images = "916415d5-f1e6-5110-898d-aaa5f9f070e0"
JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819"
MRIBase = "f7771a9a-6e57-4e71-863b-6e4b6a2f17df"
LazyArtifacts = "4af54fe1-eca0-43a8-85a7-787d91b784e3"
MAT = "23992714-dd62-5051-b70f-ba57cb901cac"
MRICoilSensitivities = "c57eb701-aafc-44a2-a53c-128049758959"
MRIFiles = "5a6f062f-bf45-497d-b654-ad17aae2a530"
MRIReco = "bdf86e05-2d2b-5731-a332-f3fe1f9e047f"
NIfTI = "a3a9e032-41b5-5fc4-967a-a6b7a19844d3"
PolygonOps = "647866c9-e3ac-4575-94e7-e3d426903924"
PyPlot = "d330b81b-6aea-500a-939a-2ce795aea3ee"
REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"
Scratch = "6c6a2e73-6563-6170-7368-637461726353"
Setfield = "efcf1570-3423-57d1-acb7-fd33fddbac46"
Expand All @@ -24,13 +30,9 @@ Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
DSP = "0.7"
DataInterpolations = "4"
FileIO = "1"
Images = "0.26"
JLD2 = "0.4"
MRIBase = "0.3"
MRICoilSensitivities = "0.1"
MRIFiles = "0.1"
MRIReco = "0.7"
NIfTI = "0.6"
PolygonOps = "0.1"
Scratch = "1"
Setfield = "1"
Expand Down
12 changes: 5 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# MRINavigator
[![Build Status](https://github.com/NordicMRspine/MRINavigator/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/NordicMRspine/MRINavigator/actions/workflows/CI.yml?query=branch%3Amain)
[![codecov.io](https://codecov.io/github/NordicMRspine/MRINavigator/coverage.svg?branch=main)](https://codecov.io/githubNordicMRspine//MRINavigator?branch=main)
[![](https://img.shields.io/badge/docs-latest-blue.svg)](https://NordicMRspine.github.io/MRINavigator/latest)

[![Build Status](https://github.com/Laura2305/MRINavigator.jl/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/Laura2305/MRINavigator.jl/actions/workflows/CI.yml?query=branch%3Amain)
[![Coverage](https://codecov.io/gh/Laura2305/MRINavigator.jl/branch/main/graph/badge.svg)](https://codecov.io/gh/Laura2305/MRINavigator.jl)

MRINavigator.jl provides multiple navigator-based correction pipelines for magnetic resonance data. These aim at demodulating time dependent field variations. The package was developed with a focus on spinal cord imaging, however it can be used for multiple imaging applications.
The corrections are to be applied on the raw data before the image reconstruction. MRIReco.jl can be used to reconstruct the images.
Expand All @@ -11,10 +12,7 @@ More details can be found in the Online Documentation (soon to be published).
MRIReco reference: https://onlinelibrary.wiley.com/doi/epdf/10.1002/mrm.28792

## How to give credit

soon to be published

[Optimised navigator correction of physiological field fluctuations in multi-echo GRE of the lumbar spinal cord at 3T](https://submissions.mirasmart.com/ISMRM2023/Itinerary/PresentationDetail.aspx?evdid=1673). L Beghini, G David, M D Liechti, S Büeler, S J Vannesjo. 2023. Proceedings of the International Society for Magnetic Resonance in Medicine (ISMRM).

## Community Standards

This project is part of the Julia community and follows the [Julia community standards](https://julialang.org/community/standards/).
This project is part of the Julia community and follows the [Julia community standards](https://julialang.org/community/standards/).
18 changes: 18 additions & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using Documenter, MRINavigator

makedocs(modules=[MRINavigator],
sitename = "MRINavigator.jl",
authors = "Laura Beghini",
pages = [
"Home" => "index.md",
"Getting Started" => "GettingStarted.md",
"Pipelines" => "Pipelines.md",
"API" => "API.md"
],
)

deploydocs(;
repo = "github.com/NordicMRspine/MRINavigator",
push_preview = true,
deploy_config = Documenter.GitHubActions(),
)
62 changes: 62 additions & 0 deletions docs/src/API.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# API

This page contains documentation of the public API of MRINavigator. In the Julia REPL one can access this documentation by entering the help mode with `?` and then writing the function for which the documentation should be shown.
For example: `? findCenterline`

# Run compact pipeline
```@docs
MRINavigator.defaultNavParams
MRINavigator.runNavPipeline
MRINavigator.saveNoise
MRINavigator.loadRawData
MRINavigator.convertRawToAcq
```


## Coil sensitivity maps
```@docs
MRINavigator.CompSensit
MRINavigator.CompRoughMask
MRINavigator.ResizeSensit!
MRINavigator.CompResizeSaveSensit
```

## Find centerline
```@docs
MRINavigator.findCenterline
MRINavigator.ReconstructMap
MRINavigator.ReconstructSaveMap
MRINavigator.callSCT
MRINavigator.comp_centerline_pos
```

## Utils
```@docs
MRINavigator.Reconstruct
MRINavigator.directreco
MRINavigator.niftiSaveImg
```

## Navigator correction
```@docs
MRINavigator.NavCorr!
MRINavigator.wrap_corr!
MRINavigator.find_wrapped
MRINavigator.TE_corr!
MRINavigator.apply_corr!
```

## Adjust data
```@docs
MRINavigator.OrderSlices!
MRINavigator.ExtractFlags
MRINavigator.ExtractNoiseData!
MRINavigator.ReverseBipolar!
MRINavigator.RemoveRef!
MRINavigator.CopyTE!
MRINavigator.AdjustSubsampleIndices!
MRINavigator.ExtractNavigator
MRINavigator.selectEcho!
MRINavigator.selectSlice!
MRINavigator.additionalNavInput
```
50 changes: 50 additions & 0 deletions docs/src/GettingStarted.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Get started

There are available [user examples](https://github.com/NordicMRspine/UserExample_MRINavigator) to get started. The user needs to provide their own data to run the pipelines, as there are currently no example data available.

## Data acquisition
The user should have the raw data of a gradient echo acquisition in an MRD format. The pipelines can be run on both multi-echo and single-echo data. Other than the main acquisition, which is usually undersampled, a lower resolution, fully sampled scan is also necessary to compute the [coils sensitivity maps](https://doi.org/10.1002/mrm.1241) and reconstruct the images. This low-resolution scan is also called a reference scan and should include only one echo. The main gradient echo acquisition must include a navigator readout through the center of k-space at __the end__ of each TR. During the acquisition, it is advisable to collect the signal from a respiratory belt as a reference. This can be used to unwrap the navigator's phase estimates if phase wrapping is present.

## Data reshaping
All the data should be exported from the scanner in raw format. Then they should be converted to [ISMRMRD](https://ismrmrd.readthedocs.io/en/latest/index.html) format. Siemens TWIX data can be converted to ISMRMRD using [siemens_to_ismrmrd](https://github.com/ismrmrd/siemens_to_ismrmrd). After the conversion, the data can be loaded into the Julia framework. Conversion of data from other vendors has not been explicitly tested by the authors.
The repiratory belt recording must be synchronised with the time stamps in the image acquisition (i.e resampled). Then they must be saved in a two-column vector (1:time [ms], 2:trace) in .mat format. Each repetition should be in a different file. The time should be expressed in seconds from the beginning of the day and contain time points before and after the image acquisition (at least 4 s).

## The parameters dictionary
Before calling the package functions, the relevant correction pipeline should be chosen and the parameters dictionary should be filled. Also the data paths and results paths need to be defined. For more details regarding the correction pipelines and parameters read the [Navigator-based correction pipelines](@ref) page.
All the information necessary to apply the corrections is defined in a [dictionary](https://docs.julialang.org/en/v1/base/collections/#Dictionaries). This includes all the file paths and analysis parameters. The user can also add items to the dictionary if needed.
Here is an example of a `params` dictionary:

```julia
params = Dict{Symbol,Any}()
params[:subject] = "sub_01"
params[:slices] = [1,2] # type nothing for all slices
params[:echoes] = [3,4] # type nothing for all echoes
params[:rep] = 0
params[:comp_sensit] = true
params[:comp_centerline] = true
params[:trust_SCT] = false
params[:use_centerline] = true
params[:corr_type] = "FFT_unwrap"
params[:FFT_interval] = 35 # millimetres
params[:root_path] = "/Users/me/my_data/"

params[:label] = params[:corr_type] * "_rep_" * string(params[:rep])
params[:path_imgData] = params[:root_path] * params[:subject] * "/h5/gre2D.h5"
params[:path_refData] = params[:root_path] * params[:subject] * "/h5/gre2D_Ref.h5"
params[:path_niftiMap] = params[:root_path] * params[:subject] * "/Nifti/gre2D_Ref.nii"
params[:path_centerline] = params[:root_path] * params[:subject] * "/Nifti/"
params[:path_physio] = params[:root_path] * params[:subject] * "/Physiological_trace/belt_reco_rep"
params[:path_sensit] = params[:root_path] * params[:subject] * "/Results/senseMap_GRE.jld2"
params[:path_noise] = params[:root_path] * params[:subject] * "/Results/noisemat.jld2"
params[:path_results] = params[:root_path] * params[:subject] * "/Results/"
params[:file_name] = "gre2D"
```

## User examples
Three user examples are available in the folder [user examples](https://github.com/NordicMRspine/UserExample_MRINavigator):
* __Compact__: runs all the selected pipeline automatically but it is not customizable and not amenable to debugging.
* __Semi-Compact__: allows for some level of customization and it is easy to debug.
* __Complete__: requires more knowledge of the data structures but it is flexible and adaptable.

## Disclaimer
Siemens data only were used to develop MRINavigator. All the functions to adjust the data before running the pipeline (e.g., the function to extract the navigator profiles or to remove the reference profiles) have been tested on Siemens data only. There is no guarantee that all of these functions are needed and will work on other vendors data. Other vendors users should convert the raw data in [ISMRMRD](https://ismrmrd.readthedocs.io/en/latest/index.html) format and when loading these into the Julia framework they should make sure that all the needed information is present. Please start from the [complete user example](https://github.com/NordicMRspine/UserExample_MRINavigator) if doing this. The functions to compute and apply the corrections should then work correctly.
32 changes: 32 additions & 0 deletions docs/src/Pipelines.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Navigator-based correction pipelines

Standard navigator processing that has been developed for brain imaging is not sufficiently robust in the spinal cord due to the following:
* Higher in-plane variability in the field distribution
* Signal-to-noise ratio (SNR) is lower
* Larger variations in signal contribution from different receiver coils compared to most anatomical regions

To face these challenges, we developed:
* __SNR weighted averaging__ of the navigator profile
* __mean phase removal__ to recenter the phase distribution and reduce wrapping
* __A fast Fourier transform (FFT) and spatial region selection step__. This consists of applying a one-dimensional Fourier transform to each navigator profile and considering for the phase estimate only the data points in a certain spatial interval centered on the spinal cord.
* __Phase unwrapping__ function for the navigator estimates using the respiratory trace recording.
These features are combined in multiple pipelines as shown in the figure.

![Pipelines](./assets/pipeline.png)

The available pipelines are:
* __k_nav__ is the k-space navigator processing commonly used for brain imaging, optimized with SNR weighted averaging and mean phase removal.
* __FFT_nav__ that includes an additional FFT and spatial region selection step compared to k_nav.
* __unwrap__ includes the phase unwrapping algorithm and makes use of the respiratory belt recordings.

MRINavigator is designed to be flexible and multiple analysis parameters are tuneable. It is possible to select the correction pipeline and parameters using the params dictionary.
For more information check the [Get started](@ref) or [API](@ref) pages. Alternatively start `julia` from the command line, and type `?` to enter the help REPL mode. Then enter

```
help?> defaultNavParams
```

Listed below are the main features and parameters the user can select and modify:
* The Spinal cord toolbox ([SCT](https://spinalcordtoolbox.com)) can be used to locate the spinal cord centerline position (`params[:comp_centerline] = true`). To do this the reference data, which are fully sampled, are reconstructed combining the coils, and saved in [NIfTI](https://brainder.org/2012/09/23/the-nifti-file-format/) format (`params[:reconstruct_map] = true`). The user can also manually locate the centerline if the automatic algorithm fails, selecting `params[:trust_SCT] = false`. Alternatively, the center of the image will be used (`params[:use_centerline] = false`).
* The interval width for the region selection after the FFT step can be adjusted (`params[:FFT_interval] = type number in millimeters`).
* The unwrap function can be applied both to the __FFT__ and the __k nav__ pipelines. To do this type `params[:corr_type] = "FFT_unwrap"` or `params[:corr_type] = "knav_unwrap"`.
Binary file added docs/src/assets/pipeline.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
67 changes: 67 additions & 0 deletions docs/src/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# MRINavigator
*Magnetic Resonance Imaging Navigator-based corrections*

## Table of contents

```@contents
Pages = [
"index.md",
"GettingStarted.md",
"Pipelines.md",
"API.md"
]
Depth = 2
```

## Introduction
MRINavigator provides multiple navigator-based correction pipelines for Magnetic Resonance (MR) images. These aim at demodulating time-dependent field variations present in multi echo-gradient echo acquisitions. The package was developed with a focus on spinal cord imaging, but it can be used for multiple imaging applications. The corrections are to be applied to the raw data before the image reconstruction. [MRIReco.jl](https://github.com/MagneticResonanceImaging/MRIReco.jl) can be used to reconstruct the images.

!!! note
MRINavigator.jl is newly published, and any feedback is welcome. Please report any bugs or feature requests as an Issue in Github.

## Installation
Start `julia` and open the package manager REPL mode by entering `]`. Then enter
```
pkg> add MRINavigator
```
This will install `MRINavigator` and all its dependencies. If you want to develop
`MRINavigator` itself you can checkout `MRINavigator` locally as usual by calling
```
pkg> dev MRINavigator
```
More information on how to develop a package can be found in the Julia documentation.

### Requirements
To use some package functionalities, external softwares are necessary.
These include:
* [Spinal Cord Toolbox (SCT)](https://spinalcordtoolbox.com)
* [FSLeyes](https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/FSLeyes)
Using these toolboxes should improve the correction outcome of the pipelines including a Fourier transform (FFT) step. Use of SCT and FSLEyes is only relevant for spinal cord acquisitions.
For additional information read the [Get started](@ref) and [Navigator-based correction pipelines](@ref) sections.

## Testing MRINavigator
To make sure that the package is correctly installed, start `julia` from the command line, type `]` to enter the package manager REPL mode. Then enter
```
pkg> test MRINavigator
```

## Updating MRINavigator
To update MRINavigator to the latest version, start `julia` from the command line, type `]` to enter the package manager REPL mode. Then enter
```
pkg> update MRINavigator
```

## Navigator-based correction
Multi-echo gradient-echo (GRE) sequences are commonly acquired both in research and clinical practice. However, one of their main limitations is the sensitivity to field instabilities both in space and time. Indeed, for the signal spatial encoding to be effective, a background homogeneous field in time and space is required. Time-varying background fields can lead to phase modulation between k-space lines, and therefore TE-dependent ghosting artefacts. [Navigator](https://www.sciencedirect.com/science/article/pii/S1053811910003356?via%3Dihub) readouts in the k-space center can be used to measure the intensity of the field fluctuations,enabling correct demodulation of the acquired signal before image reconstruction. The standard navigator-based correction was developed for brain imaging and it is not robust when applied in other areas e.g. the spinal cord. When failing, the correction can even exacerbate the problem. This package provides optimized post-processing pipelines to correct for dynamic field instabilities in GRE sequences. For additional information read the [Navigator-based correction pipelines](@ref) section.

## Plotting
`MRINavigator` does not depend upon a particular plotting package since there are various plotting packages available in Julia. Feel free to use your package of choice.

## Acknowledgements
This package uses the reconstruction functions and data structures available in [MRIReco.jl](https://github.com/MagneticResonanceImaging/MRIReco.jl).
T. Knopp and M. Grosser (2021). [MRIReco.jl: An MRI Reconstruction Framework written in Julia]( https://doi.org/10.1002/mrm.28792). Magnetic Resonance in Medicine. 2021.

## Citing this work
If you use MRINavigator in you research please cite the following:

[Optimised navigator correction of physiological field fluctuations in multi-echo GRE of the lumbar spinal cord at 3T](https://submissions.mirasmart.com/ISMRM2023/Itinerary/PresentationDetail.aspx?evdid=1673). L Beghini, G David, M D Liechti, S Büeler, S J Vannesjo. 2023. Proceedings of the International Society for Magnetic Resonance in Medicine (ISMRM).
Loading

0 comments on commit 49c4114

Please sign in to comment.