From ace8f94058b2101a11ff212ce212602d0fbf5fac Mon Sep 17 00:00:00 2001
From: Michiel Cottaar <michiel.cottaar@ndcn.ox.ac.uk>
Date: Wed, 21 Feb 2024 16:36:27 +0000
Subject: [PATCH] Add helper to intepret fov/resolution/voxel_size parameters

---
 src/MRIBuilder.jl             |  4 ++--
 src/parts/helper_functions.jl | 45 +++++++++++++++++++++++++++++++++++
 src/parts/parts.jl            |  2 +-
 3 files changed, 48 insertions(+), 3 deletions(-)

diff --git a/src/MRIBuilder.jl b/src/MRIBuilder.jl
index f0086cb..2eab1ca 100644
--- a/src/MRIBuilder.jl
+++ b/src/MRIBuilder.jl
@@ -30,8 +30,8 @@ export ContainerBlock, start_time, end_time, waveform, waveform_sequence, events
 import .Pathways: Pathway, duration_transverse, duration_dephase, bval, bmat, get_pathway
 export Pathway, duration_transverse, duration_dephase, bval, bmat, get_pathway
 
-import .Parts: dwi_gradients, readout_event, excitation_pulse, refocus_pulse, Trapezoid, SliceSelect, LineReadout, opposite_kspace_lines, SpoiltSliceSelect, SliceSelectRephase, EPIReadout
-export dwi_gradients, readout_event, excitation_pulse, refocus_pulse, Trapezoid, SliceSelect, LineReadout, opposite_kspace_lines, SpoiltSliceSelect, SliceSelectRephase, EPIReadout
+import .Parts: dwi_gradients, readout_event, excitation_pulse, refocus_pulse, Trapezoid, SliceSelect, LineReadout, opposite_kspace_lines, SpoiltSliceSelect, SliceSelectRephase, EPIReadout, interpret_image_size
+export dwi_gradients, readout_event, excitation_pulse, refocus_pulse, Trapezoid, SliceSelect, LineReadout, opposite_kspace_lines, SpoiltSliceSelect, SliceSelectRephase, EPIReadout, interpret_image_size
 
 import JuMP: @constraint, @objective, objective_function, value, Model
 export @constraint, @objective, objective_function, value, Model
diff --git a/src/parts/helper_functions.jl b/src/parts/helper_functions.jl
index 423fda2..95e6e34 100644
--- a/src/parts/helper_functions.jl
+++ b/src/parts/helper_functions.jl
@@ -217,4 +217,49 @@ function dwi_gradients(; type=:trapezoid, optimise=false, scanner=nothing, refoc
 end
 
 
+"""
+    interpret_image_size(fov, resolution, voxel_size, slice_thickness)
+
+Combines the user-provided information of the image size to produce a tuple with:
+- `slice_thickness`: if not set explicitly, will be set to the third element of `voxel_size`
+- `resolution_z`: number of voxels in the slice-select direction.
+- keywords parameters for the [`readout_event`](@ref) functions with the `fov`, `resolution`, and `voxel_size` in the x- and y- dimensions.
+"""
+function interpret_image_size(fov, resolution, voxel_size, slice_thickness)
+    _real_value(n::Number) = true
+    _real_value(n::NTuple{N, <:Number}) where {N} = true
+    _real_value(n::AbstractVector{<:Number}) = true
+    _real_value(other) = false
+
+    if all(isnothing.((fov, resolution, voxel_size)))
+        return (slice_thickness, nothing, (fov=nothing, resolution=nothing, voxel_size=nothing))
+    end
+    if !_real_value(resolution)
+        if !(_real_value(fov) && _real_value(voxel_size))
+            error("`resolution` needs to be fully defined; either by setting it directly or by setting `fov` and `voxel_size` to concrete values.")
+        end
+        resolution = Int.(div.(fov, voxel_size, RoundUp))
+        fov = resolution .* voxel_size
+    end
+
+    getz(v::Union{Tuple, AbstractVector}) = length(v) == 2 ? nothing : v[3]
+    getz(v) = v
+    if isnothing(slice_thickness)
+        slice_thickness = getz(voxel_size)
+        if isnothing(slice_thickness)
+            fovz = getz(fov)
+            if isnothing(fovz)
+                slice_thickness = Inf
+            else
+                slice_thickness = fovz / getz(resolution)
+            end
+        end
+    end
+
+    getxy(v::Union{Tuple, AbstractVector}) = [v[1], v[2]]
+    getxy(v) = [v, v]
+
+    return (slice_thickness, getz(resolution), (fov=getxy(fov), resolution=getxy(resolution), voxel_size=getxy(voxel_size)))
+end
+
 end
\ No newline at end of file
diff --git a/src/parts/parts.jl b/src/parts/parts.jl
index 0d670bc..7614397 100644
--- a/src/parts/parts.jl
+++ b/src/parts/parts.jl
@@ -9,7 +9,7 @@ import .Trapezoids: Trapezoid, SliceSelect, LineReadout, opposite_kspace_lines
 import .SpoiltSliceSelects: SpoiltSliceSelect
 import .SliceSelectRephases: SliceSelectRephase
 import .EPIReadouts: EPIReadout
-import .HelperFunctions: excitation_pulse, refocus_pulse, readout_event, dwi_gradients
+import .HelperFunctions: excitation_pulse, refocus_pulse, readout_event, dwi_gradients, interpret_image_size
 
 
 end
\ No newline at end of file
-- 
GitLab