Skip to content

Commit 42a9cff

Browse files
committed
update all
1 parent f5ca05a commit 42a9cff

File tree

7 files changed

+99
-33
lines changed

7 files changed

+99
-33
lines changed

README.md

+18-1
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,27 @@ You can install the package in any project with the following command :
116116
- enter the Julia package manager by typing `]` in the REPL. (the REPL should turn in blue)
117117
- if you want to activate an environment, type : `activate .` (otherwise the package will be installed in the global environment)
118118
- In order to add our unregistered package, type `add https://github.com/CRMSB/SEQ_BRUKER_a_MP2RAGE_CS_360`
119-
- if you want to use the package : `using SEQ_BRUKER_a_MP2RAGE_CS_360`
119+
- if you want to use the package in your script just add the following line : `using SEQ_BRUKER_a_MP2RAGE_CS_360`
120120

121121
## How to use the package
122122

123+
Follow the example in the [documentation](https://crmsb.github.io/SEQ_BRUKER_a_MP2RAGE_CS_360/dev/generated/examples/simple_reco/)
124+
125+
**Steps :**
126+
- Define the path to the bruker dataset
127+
```julia
128+
path_bruker = joinpath(datadir, "MP2RAGE_FULLY")
129+
```
130+
- Perform the reconstruction
131+
```julia
132+
d = reconstruction_MP2RAGE(path_bruker; mean_NR=true)
133+
```
134+
- write the results in the qBIDS format
135+
```julia
136+
subject_name = "sub_01"
137+
dir_path = "" # directory path where the files will be create
138+
write_bids_MP2RAGE(d,subject_name,dir_path)
139+
```
123140

124141
## Version
125142

docs/lit/examples/advanced_reco.jl

+9-12
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,12 @@ using SEQ_BRUKER_a_MP2RAGE_CS_360
1212
using CairoMakie # plotting
1313

1414
# In addition we load the package internally used to perform the reconstruction
15+
using SEQ_BRUKER_a_MP2RAGE_CS_360.MRIReco
16+
using SEQ_BRUKER_a_MP2RAGE_CS_360.MRIReco.RegularizedLeastSquares
1517

1618

17-
18-
# ## Loading Package
19-
using LazyArtifacts # loading data
20-
using SEQ_BRUKER_a_MP2RAGE_CS_360
21-
using CairoMakie # plotting
22-
19+
# ## Download the datasets
20+
# if you run the literate example offline change the following line by : `MP2_artifacts = artifact"MP2RAGE_data"
2321
datadir = Main.MP2_artifacts
2422
@info "The test data is located at $datadir."
2523

@@ -28,8 +26,7 @@ path_bruker = joinpath(datadir, "MP2RAGE_CS2")
2826

2927
# ## Compressed-sensing reconstruction
3028
# In order to use an advanced reconstruction we will pass some parameters that will be used by the reconstruction package MRIReco.jl
31-
using SEQ_BRUKER_a_MP2RAGE_CS_360.MRIReco
32-
using SEQ_BRUKER_a_MP2RAGE_CS_360.MRIReco.RegularizedLeastSquares
29+
3330

3431
# We have to create a parameter dictionnary that will be used. If you need more information about it take a look at [MRIReco.jl](https://github.com/MagneticResonanceImaging/MRIReco.jl)
3532

@@ -41,7 +38,7 @@ CS[:iterations] = 30
4138

4239
d = reconstruction_MP2RAGE(path_bruker; mean_NR=true,paramsCS = CS)
4340

44-
# for comparison purpose let's perform the undersampled reconstruction (without the paramCS keyword)
41+
# for comparison purposes let's perform the undersampled reconstruction (without the paramCS keyword)
4542
d_under = reconstruction_MP2RAGE(path_bruker; mean_NR=true)
4643

4744

@@ -56,10 +53,10 @@ begin
5653
h=heatmap!(ax,abs.(d["im_reco"][:,:,60,1,1,1]),colormap=:grays)
5754

5855

59-
ax=Axis(f[2,1],title="UNIT1 undersampled")
56+
ax=Axis(f[2,1],title="T₁ map undersampled")
6057
h=heatmap!(ax,d_under["T1map"][:,:,60,1,1],colorrange = (500,2000))
6158

62-
ax=Axis(f[2,2],title="UNIT1 CS")
59+
ax=Axis(f[2,2],title="T₁ map CS")
6360
h=heatmap!(ax,d["T1map"][:,:,60,1,1],colorrange = (500,2000))
6461

6562
for ax in f.content # hide decoration befor adding colorbar
@@ -77,4 +74,4 @@ end
7774

7875
subject_name = "sub_01_cs"
7976
dir_path = "" # directory path where the files will be create
80-
write_bids_MP2RAGE(d,subject_name,dir_path)
77+
write_bids_MP2RAGE(d,subject_name,dir_path)

docs/lit/examples/simple_reco.jl

+15-13
Original file line numberDiff line numberDiff line change
@@ -13,31 +13,31 @@ using SEQ_BRUKER_a_MP2RAGE_CS_360
1313
using CairoMakie # plotting
1414

1515
# ## Download the datasets
16-
16+
# if you run the literate example offline change the following line by : `MP2_artifacts = artifact"MP2RAGE_data"
1717
datadir = Main.MP2_artifacts
1818
@info "The test data is located at $datadir."
1919

2020
# If you want to perform your own reconstruction, you can change the following line in order to point to another a bruker dataset
2121
path_bruker = joinpath(datadir, "MP2RAGE_FULLY")
2222

2323
# ## Perform the reconstruction
24-
# this function will perform a standard reconstruction without compressed-sensing. If your data are subsampled, results will be undersampled reconstruction.
24+
# this function will perform a standard reconstruction without compressed-sensing. If your data are subsampled it will result in subsampling artifacts (blurring + noise-like)
2525
#
26-
# the keyword mean_NR=true will average the image before performing the MP2RAGE/T1 maps estimation.
26+
# the keyword mean_NR=true will average the images accross the number of repetition dimension before performing the MP2RAGE/T1 maps estimation.
2727
# Otherwise an image/T₁ map will be generated for each Number Of Repetition (NR)
2828
d = reconstruction_MP2RAGE(path_bruker; mean_NR=true)
2929

3030

3131
# the result is a dictionnary with the following fields :
32-
# - "im_reco" : (x,y,z,Number of Repetition,TI) Complex
33-
# - "MP2RAGE" : (x,y,z,TI) Float
34-
# - "T1map" : (x,y,z,Number of Repetition) Float
32+
# - "im_reco" : (x,y,z,Number of Channel , Number of Repetition,TI) Complex
33+
# - "MP2RAGE" : (x,y,z,Number of Channel , Number of Repetition) Float
34+
# - "T1map" : (x,y,z,Number of Channel , Number of Repetition) Float
3535
# - "params_prot"
3636
# - "params_reco"
3737
# - "params_MP2RAGE"
3838
#
39-
# im_reco corresponds to the TI₁ and \TI₂ images in the complex format with 6 dimensions :
40-
# (x,y,z,Number of Repetition,TI)
39+
# im_reco corresponds to the TI₁ and TI₂ images in the complex format with 6 dimensions :
40+
# (x,y,z, Number of Channel , Number of Repetition,TI)
4141

4242

4343
# We can check the results
@@ -53,7 +53,7 @@ begin
5353
ax=Axis(f[2,1],title="UNIT1 / MP2RAGE")
5454
h=heatmap!(ax,d["MP2RAGE"][:,:,60,1,1],colormap=:grays)
5555

56-
ax=Axis(f[2,2],title="UNIT1 / MP2RAGE")
56+
ax=Axis(f[2,2],title="T₁ map")
5757
h=heatmap!(ax,d["T1map"][:,:,60,1,1],colorrange = (500,2000))
5858

5959
for ax in f.content # hide decoration befor adding colorbar
@@ -64,8 +64,8 @@ begin
6464
f
6565
end
6666

67-
# The Lookup table used for the reconstruction is stored in the dictionnary (LUT)
68-
# First columns is the range of T1.
67+
# The Lookup table used for the reconstruction is stored in the dictionnary (LUT).
68+
# First dimension is the range of T1 and the 2nd is the expected value of the MP2RAGE signal between -0.5 to 0.5.
6969
f=Figure()
7070
ax = Axis(f[1,1],xlabel="T₁ [ms]")
7171
lines!(ax,d["LUT"])
@@ -94,7 +94,9 @@ sub_01/
9494
└─ sub_01_inv-2-phase_MP2RAGE.nii.gz
9595
```
9696
97-
If you want to generate the T1 map with another tools like qMRLab
98-
the required MP2RAGE parameters are stored in the **MP2RAGE.json** file.
97+
For simplicity the T₁ map is stored in the anat/ folder like the ones created by Siemens.
98+
99+
If you want to generate the T1 map with another tool like qMRLab
100+
the required MP2RAGE parameters are stored in the **MP2RAGE.json** file. In that case the data are supposed to be stored in a derivatives folder (see[qBIDS format recommandation](https://bids-specification.readthedocs.io/en/stable/appendices/qmri.html))
99101
=#
100102

docs/make.jl

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ makedocs(;
2222
"Home" => "index.md",
2323
"Examples" =>["generated/examples/simple_reco.md",
2424
"generated/examples/advanced_reco.md"],
25+
"API" => "api.md"
2526
],
2627
)
2728

src/BIDS.jl

+6-5
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@ This function writes data from a dictionary (`d`) in BIDS (Brain Imaging Data St
77
88
**Arguments:**
99
10-
* `d` (Dict): A dictionary containing the data to be written. Expected keys:
10+
* `d` (Dict): A dictionary containing the data to be written. Expected key-value pairs:
1111
* `im_reco` (Array): 5D array containing the reconstructed images.
12-
* `MP2RAGE` (Array): T1 map image.
13-
* `T1maps` (Array): Additional T1 map data (optional).
14-
* `params_prot` (Dict): Dictionary containing acquisition parameters.
15-
* `params_MP2RAGE` (Dict): Dictionary containing MP2RAGE specific parameters.
12+
* `MP2RAGE` (Array): Combined MP2RAGE image data.
13+
* `T1map` (Array): Calculated T1 map from MP2RAGE images.
14+
* `params_prot` (Dict): Protocol parameters extracted from the Bruker file.
15+
* `params_MP2RAGE` (Struct): Dictionary containing MP2RAGE specific parameters.
16+
1617
* `subname` (AbstractString): The name of the subject.
1718
* `folder` (AbstractString, optional): The folder where the BIDS data will be written. Defaults to the current directory.
1819

src/bruker_sequence.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ export RawAcquisitionData_MP2RAGE
33
"""
44
RawAcquisitionData_MP2RAGE(b::BrukerFile)
55
6-
Convert a Bruker dataset acquired with the a_MP2RAGE_CS_360 sequence into a
6+
Convert a Bruker dataset acquired with the a\\_MP2RAGE\\_CS\\_360 sequence into a
77
`RawAcquisitionData` object compatible with the MRIReco functions.
88
99
Input :

src/reconstruction.jl

+49-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,41 @@
1-
export reconstruction_MP2RAGE
1+
export reconstruction_MP2RAGE, params_from_seq
2+
3+
"""
4+
reconstruction_MP2RAGE(path_bruker::String; mean_NR::Bool = false, paramsCS::Dict = Dict())
5+
6+
Reconstructs MP2RAGE MRI data from a specified Bruker file path, returning images and T1 maps.
7+
8+
# Arguments
9+
- `path_bruker::String`: Path to the Bruker file containing MRI acquisition data.
10+
- `mean_NR::Bool`: If `true`, calculates the mean of the reconstructed data accross the repetition (default: `false`).
11+
- `paramsCS::Dict`: Optional dictionary for customizing reconstruction parameters. These values override the default parameter dictionary (`params`).
12+
13+
# Returns
14+
A dictionary with the following key-value pairs:
15+
- `"im_reco"`: Reconstructed MP2RAGE image array, permuted to match the expected order.
16+
- `"MP2RAGE"`: Combined MP2RAGE image data.
17+
- `"T1map"`: Calculated T1 map from MP2RAGE images.
18+
- `"params_reco"`: Dictionary of parameters used for reconstruction.
19+
- `"params_MP2RAGE"`: Sequence parameters derived from the Bruker file.
20+
- `"params_prot"`: Protocol parameters extracted from the Bruker file.
21+
- `"LUT"`: Lookup table with T1 range and associated values.
22+
23+
# Description
24+
The function performs the following steps:
25+
1. Reads acquisition data from the Bruker file at `path_bruker`.
26+
2. Constructs calibration data using an ESPIRiT sensitivity map from low-resolution data.
27+
3. Sets reconstruction parameters, allowing for custom parameters specified in `paramsCS`.
28+
4. Reconstructs the MP2RAGE image data and optionally averages across repeated measurements.
29+
5. Permutes the resulting array dimensions for compatibility.
30+
6. Extracts T1 maps from MP2RAGE images and constructs a lookup table (`LUT`).
31+
32+
# Example
33+
```julia
34+
d = reconstruction_MP2RAGE("path/to/bruker_data", mean_NR = true, paramsCS = Dict(:iterations => 5))
35+
println(d["T1map"])
36+
```
37+
38+
"""
239

340
function reconstruction_MP2RAGE(path_bruker;mean_NR::Bool = false,paramsCS=Dict())
441
b = BrukerFile(path_bruker)
@@ -45,6 +82,17 @@ function reconstruction_MP2RAGE(path_bruker;mean_NR::Bool = false,paramsCS=Dict(
4582
return d
4683
end
4784

85+
"""
86+
params_from_seq(b::BrukerFile)
87+
88+
Extracts MP2RAGE sequence parameters from a Bruker file and returns them in a `ParamsMP2RAGE` structure.
89+
90+
# Arguments
91+
- `b::BrukerFile`: Bruker file containing sequence parameter information.
92+
93+
# Returns
94+
A `ParamsMP2RAGE` structure containing key sequence timings and settings for MP2RAGE reconstruction.
95+
"""
4896
function params_from_seq(b::BrukerFile)
4997
return ParamsMP2RAGE(
5098
parse(Float64,b["EffectiveTI"][1]),

0 commit comments

Comments
 (0)