Skip to content

Commit

Permalink
Merge branch 'setup' into documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
Laura2305 authored Aug 31, 2023
2 parents e231e96 + 2a8ee1c commit 07b9410
Show file tree
Hide file tree
Showing 10 changed files with 44 additions and 43 deletions.
3 changes: 2 additions & 1 deletion docs/src/API.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# 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.
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
Expand Down
2 changes: 1 addition & 1 deletion docs/src/Pipelines.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ help?> defaultNavParams
Here are listed 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 selected (`params[:FFT_interval] = type number in millimeters`).
* The unwrap function can be applied added both to the __FFT__ and the __k nav__ pipelines. To do this type `params[:corr_type] = "FFT_unwrap"` or `params[:corr_type] = "knav_unwrap"`.
* The unwrap function can be applied added both to the __FFT__ and the __k nav__ pipelines. To do this type `params[:corr_type] = "FFT_unwrap"` or `params[:corr_type] = "knav_unwrap"`.
10 changes: 5 additions & 5 deletions src/AdjustData.jl
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ end
flags = ExtractFlags(rawData::RawAcquisitionData)
Extract the acquisition flags from the MRIReco.jl raw data profiles.
Return a 31 elements vector for each profile.
Return a 31-element vector for each profile.
MRIReco reference: https://onlinelibrary.wiley.com/doi/epdf/10.1002/mrm.28792
Expand All @@ -62,7 +62,7 @@ end
Extract and return the noise acquisition from the MRIReco.jl raw data.
The noise acquisition is usually the first profile with slice = 0, contrast = 0, repetition = 0.
The noise profile should have the 19th flag element qual to 1. Check with ExtractFlags if errors occur.
The noise profile should have the 19th flag element equal to 1. Check this with ExtractFlags if errors occur.
MRIReco reference: https://onlinelibrary.wiley.com/doi/epdf/10.1002/mrm.28792
Expand Down Expand Up @@ -133,7 +133,7 @@ end
Remove reference data that are not useful for the navigator-based correction from acquisitions with phase stabilization on Siemens scanners.
Make sure that this is needed on your data checking the time stamps with mapVBVD in Matlab.
Not solid to recalls.
Not robust to repeated calls, modifies rawData.
MRIReco reference: https://onlinelibrary.wiley.com/doi/epdf/10.1002/mrm.28792
mapVBVD reference: https://github.com/CIC-methods/FID-A/blob/master/inputOutput/mapVBVD/README.md
Expand Down Expand Up @@ -177,7 +177,7 @@ end
AdjustSubsampleIndices!(acqData::AcquisitionData)
Add subsamples indices in the MRIReco.jl acquisition data structure.
Needed when conveting data not acquired in the first repetition.
Needed when converting data not acquired in the first repetition.
MRIReco reference: https://onlinelibrary.wiley.com/doi/epdf/10.1002/mrm.28792
Expand All @@ -202,7 +202,7 @@ end
Extract the navigator profiles from the MRIReco.jl raw data structure.
These are registered with the same indices (contract, slice, encoding step) as the image data for the first echo time.
Return a navigator array and a navigator time array. The navigator array has four dimensions in order: k-space samples, coils, k-space lines, slices.
Return a navigator array and a navigator time array. The navigator array has four dimensions in the following order: k-space samples, coils, k-space lines, slices.
Effective only if the navigator profile was acquired after the first image profile.
MRIReco reference: https://onlinelibrary.wiley.com/doi/epdf/10.1002/mrm.28792
Expand Down
18 changes: 9 additions & 9 deletions src/CoilSensMap.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ MRIReco reference: https://onlinelibrary.wiley.com/doi/epdf/10.1002/mrm.28792
# Arguments
* `acqData::RawAcquisitionData` - acquisition data structure obtained converting raw data with MRIReco.jl
* `tresh::Float64` - masking treshold: increase for reduced mask size, decrease for extended mask size
* `tresh::Float64` - masking threshold: increase for reduced mask size, decrease for extended mask size
"""
function CompSensit(acq::AcquisitionData, thresh = 0.13)

Expand Down Expand Up @@ -45,7 +45,7 @@ Return a rough mask for multiple slices that may not be homogeneous.
# Arguments
* `acqData::RawAcquisitionData` - acquisition data structure obtained converting raw data with MRIReco.jl
* `slices::Int64` - number of slices in acquisition data
* `tresh::Float64` - masking treshold: increase for reduced mask size, decrease for extended mask size
* `tresh::Float64` - masking threshold: increase for reduced mask size, decrease for extended mask size
MRIReco reference: https://onlinelibrary.wiley.com/doi/epdf/10.1002/mrm.28792
"""
Expand All @@ -68,14 +68,14 @@ end
"""
findConnectedComponent!(mask_slice::Array{T,2})
Return the biggest connected component for a mask slice.
Return the largest connected component for a mask slice.
# Arguments
* `mask_slice::Array{T,2}` - mask for one slice with the same resolution as the reference data
"""
function findConnectedComponent!(mask_slice::Array{T,2}) where {T}

# Find and keep only the biggest connected componet in the image
# Find and keep only the largest connected component in the image
components = label_components(mask_slice)
measured_area = component_lengths(components)
measured_area = measured_area[2:end] #remove background component
Expand All @@ -88,8 +88,8 @@ end
"""
removeBehindBack!(mask_slice::Array{T,2})
Removes the voxels behind the subject's back, asuming that this is in the left half side of the image.
To do this: compute the points density in the phase encoding direction, compute the density derivative and find the maximum in the left half of the image.
Removes the voxels behind the subject's back, assuming that this is in the left half side of the image.
To do this: compute the points density in the phase encoding direction, compute the density derivative and find the maximum in the left half of the image.
Add a 3 voxels safety margin.
# Arguments
Expand Down Expand Up @@ -128,8 +128,8 @@ Make the mask uniform for a single slice using a convex hull function.
function homogeneousMask!(mask_slice::Array{T,2}) where{T}

cartes_index_slice = CartesianIndices(mask_slice)
Bimask_slice = convert(BitMatrix, mask_slice)
hull = convexhull(Bimask_slice)
Bitmask_slice = convert(BitMatrix, mask_slice)
hull = convexhull(Bitmask_slice)

push!(hull, hull[1])

Expand Down Expand Up @@ -159,7 +159,7 @@ function ResizeSensit!(sensit::Array{Complex{T},4}, acqMap::AcquisitionData, acq
sizeSensit = size(sensit)

if freq_enc_samples[1] != sizeSensit[1] && freq_enc_samples[2] != sizeSensit[2]
@warn "The coils sensitivity maps have already been resized, the function cannot be executed."
@warn "The coil sensitivity maps have already been resized, the function cannot be executed."

elseif freq_enc_FoV[1] < freq_enc_FoV[2] || phase_enc_FoV[1] < phase_enc_FoV[2]
@error "The reference data field of view is smaller than the image data field of view."
Expand Down
2 changes: 1 addition & 1 deletion src/NavData.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ end
trace::Union{Matrix{Float64}, Nothing} = nothing,
centerline::Union{Vector{Float64}, Nothing} = nothing)
Construct the additional data structure that is needed as imput to navCorr!
Construct the additional data structure that is needed as input to navCorr!
# Arguments
* `noisemat::Array{Complex{Float32}, 2}` - noise data obtained with ExtractNoiseData!
Expand Down
8 changes: 4 additions & 4 deletions src/Navigator.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export NavCorr!, comp_centerline_pos, wrap_corr!, TE_corr!, apply_corr!
Compute the navigator-based correction and apply it to the acquisition data. Multiple pipelines are available: "knav", "FFT" and "FFT_unwrap".
Return navigator trace, spinal cord centerline in the reconstructed image coordinates,
Correlation between nagigator and belt data for each slice and position of wrapped points for each slices.
Correlation between navigator and belt data for each slice and position of wrapped points for each slices.
Please choose the pipeline using the corr_type filed in the params dictionary.
# Arguments
Expand All @@ -19,13 +19,13 @@ MRIReco reference: https://onlinelibrary.wiley.com/doi/epdf/10.1002/mrm.28792
"""
function NavCorr!(nav::Array{Complex{T}, 4}, acqData::AcquisitionData, params::Dict{Symbol, Any}, addData::additionalNavInput) where{T}

#navigator[k-space samples, coils, k-space lines, slices]
# navigator[k-space samples, coils, k-space lines, slices]
# compute the navigator fourier transform in the readout direction, only for FFT case
centerline = nothing
corr_type = split(params[:corr_type], "_")
if corr_type[1] != "knav"
nav = ifftshift(ifft(fftshift(nav, [1]), [1]), [1])
#noisemat = fftshift(fft(ifftshift(noisemat, [1]), [1]), [1])
# noisemat = fftshift(fft(ifftshift(noisemat, [1]), [1]), [1])

nav_center = div(addData.numsamples, 2)
if params[:use_centerline] == true
Expand Down Expand Up @@ -145,7 +145,7 @@ end
nav = TE_corr!(nav::Array{T, 4}, acqd::AcquisitionData, dt_nav::Float64, TE_nav::Float64, numsamples::Int64, numechoes::Int64) where {T}
Compute the phase value for the navigator correction basing on the exact acquisition time of each data sample in the line and for each echo.
Return a four dimensional navigator array.
Return a four-dimensional navigator array.
# Arguments
* `nav::Array{T, 4}` - phase estimates obtained from the navigator data
Expand Down
6 changes: 3 additions & 3 deletions src/Reconstruction.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ Call MRIReco.jl reconstruction function and return reconstructed image. Only sin
# Arguments
* `acqData::RawAcquisitionData` - acquisition data structure obtained converting raw data with MRIReco.jl
* `sensit::Array{Complex{T},4}` - coil sensitivity map matric computed with CompSensit(acq::AcquisitionData, thresh = 0.135)
* `noisemat::Union{Array{Complex{T}},Nothing} = nothing` - noise data extracted from the raw datat structure with ExtractNoiseData!(rawData::RawAcquisitionData)
* `sensit::Array{Complex{T},4}` - coil sensitivity map matrix computed with CompSensit(acq::AcquisitionData, thresh = 0.135)
* `noisemat::Union{Array{Complex{T}},Nothing} = nothing` - noise data extracted from the raw data structure with ExtractNoiseData!(rawData::RawAcquisitionData)
MRIReco reference: https://onlinelibrary.wiley.com/doi/epdf/10.1002/mrm.28792
"""
Expand Down Expand Up @@ -41,7 +41,7 @@ end
"""
img = directreco(acq::AcquisitionData)
Call MRIReco.jl reocnstruction function and return reconstructed image. Reconstruct coils separately.
Call MRIReco.jl reconstruction function and return reconstructed image. Reconstruct coils separately.
# Arguments
* `acqData::RawAcquisitionData` - acquisition data structure obtained converting raw data with MRIReco.jl
Expand Down
2 changes: 1 addition & 1 deletion src/SpineCenterline.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export ReconstructSaveMap, ReconstructMap, niftiSaveImg, callSCT, findCenterline
"""
ReconstructSaveMap(path_nifti::String, path_ref::String)
Reconstruct the coil sensitivity map using the MRIReco.jl function and save it in nifti format without spatial informations.
Reconstruct the coil sensitivity map using the MRIReco.jl function and save it in nifti format without spatial information.
# Arguments
* `path_nifti::String` - path of the nifti file. The file must have .nii extension
Expand Down
30 changes: 15 additions & 15 deletions src/Unwrap.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ Return the position of the wrapped points and the correlation between each navig
# Arguments
* `nav::Array{Float64, 4}` - navigator phase estimates
* `nav_time::Array{Float64, 2}` - navigator data time stamps in ms from the beginning of the day, for each slice
* `trace::Array{Float64, 2}` - physiological trace recording. Two columns vector (1:time [ms], 2:trace). The first column contains the time stamps in ms from the beginning of the day.
* `nav_time::Array{Float64, 2}` - navigator data timestamps in ms from the beginning of the day, for each slice
* `trace::Array{Float64, 2}` - physiological trace recording. Two columns vector (1:time [ms], 2:trace). The first column contains the timestamps in ms from the beginning of the day.
Include time points before and after the image acquisition (at least 2 s).
* `slices::Int64` - number of slices
"""
Expand Down Expand Up @@ -81,7 +81,7 @@ function find_wrapped(nav::Array{Float64, 4}, nav_time::Array{Float64, 2}, trace
end
end

if mean(correlation) < 0.2 # consider the trace inaccurate
if mean(correlation) < 0.2 # check for inaccurate trace (arbitrary threshold, adjust if necessary)
possible_wrap_slices .== false
end

Expand Down Expand Up @@ -112,7 +112,7 @@ end
"""
trace_data = smooth_lowpass(time::Array{Float64, 1}, trace_data::Array{Float64, 1})
Smooth the physiological trace recording using a butterworth low-pass filter (cut-off frequency 0.7Hz, 3 poles)
Smooth the physiological trace recording using a Butterworth low-pass filter (cut-off frequency 0.7Hz, 3 poles)
# Arguments
* `time::Array{Float64, 1}` - time in ms from the beginning of the day for the belt recording
Expand All @@ -130,10 +130,10 @@ end
"""
nav_norm = smooth_highpass(nav_time::Array{Float64, 2}, nav_norm::Array{Float64, 2}, slices:: Int64)
Remove the low frequencies components from the navigatior phase estimate using a butterworth high-pass filter (cut-off frequency 0.5Hz, 3 poles)
Remove the low frequencies components from the navigator phase estimate using a Butterworth high-pass filter (cut-off frequency 0.5Hz, 3 poles)
# Arguments
* `nav_time::Array{Float64}` - navigator data time stamps in ms from the beginning of the day, for each slice
* `nav_time::Array{Float64}` - navigator data timestamps in ms from the beginning of the day, for each slice
* `nav_norm::Array{Float64}` - navigator phase estimates
* `slices::Int64` - number of slices
"""
Expand Down Expand Up @@ -161,7 +161,7 @@ end
nav_time::Union{Matrix{Float64}, Vector{Float64}},
time::Union{Matrix{Float64}, Vector{Float64}}, slices = 0)
Interpolate the first input vector with time stamps specified in the second input to the time points specified in the third input.
Interpolate the first input vector with timestamps specified in the second input to the time points specified in the third input.
Return the interpolartion result.
# Arguments
Expand Down Expand Up @@ -213,7 +213,7 @@ Return correlation = 0.1 if data is Nan.
* `nav_int::Array{Float64, 2}` - navigator phase estimes
* `trace_data::Array{Float64, 2}` - physiological trace recording from the respiratory belt
* `slices::Int64` - number of slices
* `allData::Bool` - use all the time points if true. Use only the lower time points in the belt trace if false, hopefully escluding wrapped points in the navigator
* `allData::Bool` - use all the time points if true. Use only the lower time points in the belt trace if false, hopefully excluding wrapped points in the navigator
"""
function signalCorrelation(nav_int::Array{Float64, 2}, trace_data::Array{Float64, 2}, slices::Int64, allData = true)

Expand Down Expand Up @@ -245,7 +245,7 @@ end
"""
invertNavSign!(nav::Union{Array{Float64, 2}, Array{Float64, 4}}, correlation::Union{Array{Float64, 1}, Matrix{Float64}}, slices::Int64)
Invert the navigator phase estimates sign if the correlation between the respiratory trace and the navigator esimates is negative.
Invert the navigator phase estimate sign if the correlation between the respiratory trace and the navigator estimate is negative.
# Arguments
* `nav::Array{Float64, 2}` - navigator phase estimes
Expand Down Expand Up @@ -276,15 +276,15 @@ end
"""
trace_time = align(nav_align::Array{Float64, 1}, nav_time_align::Array{Float64, 1}, trace_data::Array{Float64, 1}, time::Array{Float64, 1})
Align the signal in the first imput (time stamps in the second imput) to the signal in the third imput (time stamps in the fourth input).
Align the signal in the first imput (timestamps in the second imput) to the signal in the third imput (timestamps in the fourth input).
Use the finddelay function from DSP.jl, find the peak of the signals cross-correlation.
Return the new time vector for the signal in the third input.
# Arguments
* `nav_align::Array{Float64, 2}` - navigator phase estimes reshaped in one vector
* `nav_time_align::Array{Float64, 1}` - time stamps for the navigator phase estimates in ms from the beginning of the day
* `nav_time_align::Array{Float64, 1}` - timestamps for the navigator phase estimates in ms from the beginning of the day
* `trace_data::Array{Float64, 1}` - respiratory belt recording in ms from the beginning of the day
* `time::Array{Float64, 1}` - time stamps for the respiratory belt recording in se
* `time::Array{Float64, 1}` - timestamps for the respiratory belt recording in se
"""
function align(nav_align::Array{Float64, 1}, nav_time_align::Array{Float64, 1}, trace_data::Array{Float64, 1}, time::Array{Float64, 1})

Expand All @@ -305,9 +305,9 @@ end
"""
correlation = find_field_changes(correlation::Union{Array{Float64, 1}, Matrix{Float64}})
Inhale air can lead to both positive and negative field variations depensing by the vertebral level.
Inhaled air can lead to both positive and negative field variations depending on the vertebral level.
There are two regions where the field variations change sign, at the lungs extremities.
It is reasonable to assume that MRI using a commercial spinal coil can not allow to record both these regions in the same acquisition.
It is reasonable to assume that MRI using a commercial spinal coil cannot allow to record both these regions in the same acquisition.
Therefore, only one field change in the correlation sign across slices should be allowed.
This function works only if the number of slices is bigger than 5.
Expand Down Expand Up @@ -427,7 +427,7 @@ Find wrapped points comparing the breathing related oscillations measured with t
Return a binary array, with the same size as nav_norm and 1 if the point is idenfied as wrapped.
# Arguments
* `nav_norm::Array{Float64, 2}` - navigator phase estimes
* `nav_norm::Array{Float64, 2}` - navigator phase estimates
* `trace_data_int::Array{Float64, 2}` - trace data smoothed, and interpolated to the navigator time points for each slice
* `slices::Int64` - number of slices
"""
Expand Down
6 changes: 3 additions & 3 deletions src/main.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ export runNavPipeline, saveNoise, loadRawData, convertRawToAcq
"""
runNavPipeline(params::Dict{Symbol, Any})
Run the navigator pipeline. Return reconstructed image and navigaotr correction output (check NavCorr!).
Run the navigator pipeline. Return reconstructed image and navigator correction output (check NavCorr!).
# Arguments
* `params::Dict{Symbol, Any}` - MRINavigator parameter structure, check defaultNavParams() for info
Expand All @@ -19,7 +19,7 @@ function runNavPipeline(params::Dict{Symbol, Any})
noisemat = FileIO.load(params[:path_noise], "noisemat")

@info "Extract navigator data. The time stamps are accurate only for Siemens data."
@info "The navigaotr extraction is effective only if the navigator profile was acquired after the first image profile."
@info "The navigator extraction is effective only if the navigator profile was acquired after the first image profile."
(nav, nav_time) = ExtractNavigator(rawData)
nav_time = nav_time .* 2.5 # seconds from beginning of the day (Siemens data only)

Expand Down Expand Up @@ -134,7 +134,7 @@ function loadRawData(params::Dict{Symbol, Any})
rawData = @set rawData.profiles[ii].head.idx.repetition = 0
end
else
ExtractNoiseData!(rawData) # remove the noise acquisition only necessary for the first rep
ExtractNoiseData!(rawData) # removing the noise acquisition is only necessary for the first rep
end
OrderSlices!(rawData)
ReverseBipolar!(rawData)
Expand Down

0 comments on commit 07b9410

Please sign in to comment.