From de6cb4c6143bdff77129c1d54e8e336a6dc6d608 Mon Sep 17 00:00:00 2001 From: Michiel Cottaar <michiel.cottaar@ndcn.ox.ac.uk> Date: Thu, 15 Feb 2024 18:28:57 +0000 Subject: [PATCH] Add group and orientation to gradient blocks --- .../changing_gradient_blocks.jl | 18 +++++++++++++----- .../constant_gradient_blocks.jl | 18 +++++++++++++----- .../gradient_waveforms/no_gradient_blocks.jl | 9 +++++---- 3 files changed, 31 insertions(+), 14 deletions(-) diff --git a/src/components/gradient_waveforms/changing_gradient_blocks.jl b/src/components/gradient_waveforms/changing_gradient_blocks.jl index f81715f..c3eb4cf 100644 --- a/src/components/gradient_waveforms/changing_gradient_blocks.jl +++ b/src/components/gradient_waveforms/changing_gradient_blocks.jl @@ -5,26 +5,30 @@ import ...AbstractTypes: GradientWaveform """ - ChangingGradient(grad1, slew_rate, duration) + ChangingGradient(grad1_scalar, slew_rate_scalar, orientation, duration, group=nothing) + ChangingGradient(grad1_vec, slew_rate_vec, duration, group=nothing) -Underlying type for any linearly changing part in a 1D or 3D gradient waveform (depending on whether `grad1` and `slew_rate` are a scalar or a vector) +Underlying type for any linearly changing part in a 1D (first constructor) or 3D (second constructor) gradient waveform. Usually, you do not want to create this object directly, use a `BuildingBlock` instead. """ abstract type ChangingGradient{N} <: GradientWaveform{N} end -(::Type{ChangingGradient})(grad1::VariableType, slew_rate::VariableType, duration::VariableType) = ChangingGradient1D(grad1, slew_rate, duration) -(::Type{ChangingGradient})(grad1::AbstractVector, slew_rate::AbstractVector, duration::VariableType) = ChangingGradient3D(grad1, slew_rate, duration) +(::Type{ChangingGradient})(grad1::VariableType, slew_rate::VariableType, orientation::AbstractVector, duration::VariableType, group=nothing) = ChangingGradient1D(grad1, slew_rate, orientation, duration, group) +(::Type{ChangingGradient})(grad1::AbstractVector, slew_rate::AbstractVector, duration::VariableType, group=nothing) = ChangingGradient3D(grad1, slew_rate, duration, group) struct ChangingGradient1D <: ChangingGradient{1} gradient_strength_start :: VariableType slew_rate :: VariableType + orientation :: SVector{3, Float64} duration :: VariableType + group :: Union{Nothing, Symbol} end struct ChangingGradient3D <: ChangingGradient{3} gradient_strength_start :: SVector{3, <:VariableType} slew_rate :: SVector{3, <:VariableType} duration :: VariableType + group :: Union{Nothing, Symbol} end @@ -80,7 +84,11 @@ For N times this returns a vector with the N+1 replacement [`ConstantGradientBlo function split_gradient(cgb::ChangingGradient, times::VariableType...) all_times = [0., times...] durations = [times[1], [t[2] - t[1] for t in zip(times[1:end-1], times[2:end])]..., duration(cgb) - times[end]] - return [cls(cgb)(cgb.gradient_strength .+ cgb.slew_rate .* t, cgb.slew_rate, d) for (t, d) in zip(all_times, durations)] + if cgb isa ChangingGradient1D + return [ChangingGradient1D(cgb.gradient_strength .+ cgb.slew_rate .* t, cgb.slew_rate, cgb.orientation, d, cgb.group) for (t, d) in zip(all_times, durations)] + else + return [ChangingGradient3D(cgb.gradient_strength .+ cgb.slew_rate .* t, cgb.slew_rate, d, cgb.group) for (t, d) in zip(all_times, durations)] + end end diff --git a/src/components/gradient_waveforms/constant_gradient_blocks.jl b/src/components/gradient_waveforms/constant_gradient_blocks.jl index eab1060..7a54528 100644 --- a/src/components/gradient_waveforms/constant_gradient_blocks.jl +++ b/src/components/gradient_waveforms/constant_gradient_blocks.jl @@ -5,24 +5,28 @@ import ...AbstractTypes: GradientWaveform import ..ChangingGradientBlocks: split_gradient """ - ConstantGradient(gradient_strength, duration) + ConstantGradient(gradient_strength_vector, duration, group=nothing) + ConstantGradient(gradient_strength_scalar, orientation, duration, group=nothing) -Underlying type for any flat part in a 1D or 3D gradient waveform (depending on whether `gradient_strength` is a scalar or a vector). +Underlying type for any flat part in a 3D (first constructor) or 3D (second constructor) gradient waveform. Usually, you do not want to create this object directly, use a `BuildingBlock` instead. """ abstract type ConstantGradient{N} <: GradientWaveform{N} end -(::Type{ConstantGradient})(grad1::VariableType, duration::VariableType) = ConstantGradient1D(grad1, duration) -(::Type{ConstantGradient})(grad1::AbstractVector, duration::VariableType) = ConstantGradient3D(grad1, duration) +(::Type{ConstantGradient})(grad1::VariableType, orientation::AbsractVector, duration::VariableType, group=nothing) = ConstantGradient1D(grad1, duration, orientation, group) +(::Type{ConstantGradient})(grad1::AbstractVector, duration::VariableType, group=nothing) = ConstantGradient3D(grad1, duration, group) struct ConstantGradient1D <: ConstantGradient{1} gradient_strength :: VariableType + orientation :: SVector{3, Float64} duration :: VariableType + group :: Union{Symbol, Nothing} end struct ConstantGradient3D <: ConstantGradient{3} gradient_strength :: SVector{3, <:VariableType} duration :: VariableType + group :: Union{Symbol, Nothing} end duration(cgb::ConstantGradient) = cgb.duration @@ -55,7 +59,11 @@ end function split_gradient(cgb::ConstantGradient, times::VariableType...) durations = [times[1], [t[2] - t[1] for t in zip(times[1:end-1], times[2:end])]..., duration(cgb) - times[end]] - return [typeof(cgb)(cgb.gradient_strength, d) for d in durations] + if cgb isa ConstantGradient1D + return [ConstantGradient1D(cgb.gradient_strength, cgb.orientation, d, cgb.group) for d in durations] + else + return [ConstantGradient3D(cgb.gradient_strength, d, cgb.group) for d in durations] + end end end diff --git a/src/components/gradient_waveforms/no_gradient_blocks.jl b/src/components/gradient_waveforms/no_gradient_blocks.jl index 08e22a4..8bc9548 100644 --- a/src/components/gradient_waveforms/no_gradient_blocks.jl +++ b/src/components/gradient_waveforms/no_gradient_blocks.jl @@ -1,6 +1,6 @@ module NoGradientBlocks import StaticArrays: SVector, SMatrix -import ....Variables: VariableType, duration, qvec, bmat_gradient, gradient_strength, slew_rate, get_free_variable +import ....Variables: VariableType, duration, qval, qvec, bmat_gradient, gradient_strength, slew_rate, get_free_variable import ...AbstractTypes: GradientWaveform import ..ChangingGradientBlocks: split_gradient @@ -24,15 +24,16 @@ struct NoGradient{N} <: GradientWaveform{N} end duration(ngb::NoGradient) = duration(ngb) -for func in (:qvec, :gradient_strength, :slew_rate) +for func in (:qval, :gradient_strength, :slew_rate) @eval $func(::NoGradient{1}) = 0. @eval $func(::NoGradient{3}) = zero(SVector{3, Float64}) end +qvec(::NoGradient, index1, index2) = zero(SVector{3, Float64}) +qvec(::NoGradient) = zero(SVector{3, Float64}) + bmat_gradient(::NoGradient{1}) = 0. bmat_gradient(::NoGradient{3}) = zero(SMatrix{3, 3, Float64, 9}) - -bmat_gradient(::NoGradient, ) = 0. bmat_gradient(ngb::NoGradient{1}, qstart::VariableType) = qstart^2 * duration(ngb) bmat_gradient(ngb::NoGradient{3}, qstart::AbstractVector{<:VariableType}) = @. qstart * permutedims(qstart) * duration(ngb) -- GitLab