From 79cefb01846d0e366e7ae789f08e3d7c7c49eb40 Mon Sep 17 00:00:00 2001 From: Michiel Cottaar <MichielCottaar@protonmail.com> Date: Sat, 25 May 2024 15:51:45 +0100 Subject: [PATCH] Assign type to variables --- .../gradient_waveforms/changing_gradient_blocks.jl | 4 +++- .../gradient_waveforms/constant_gradient_blocks.jl | 6 ++++-- src/components/gradient_waveforms/no_gradient_blocks.jl | 2 +- src/components/instant_gradients.jl | 6 +++--- src/components/pulses/composite_pulses.jl | 5 +++-- src/components/pulses/constant_pulses.jl | 9 +++++---- src/components/pulses/generic_pulses.jl | 9 +++++---- src/components/pulses/sinc_pulses.jl | 4 ++-- src/components/readouts/ADCs.jl | 6 +++--- src/containers/building_blocks.jl | 2 +- src/parts/epi_readouts.jl | 8 ++++---- 11 files changed, 34 insertions(+), 27 deletions(-) diff --git a/src/components/gradient_waveforms/changing_gradient_blocks.jl b/src/components/gradient_waveforms/changing_gradient_blocks.jl index b831687..db27616 100644 --- a/src/components/gradient_waveforms/changing_gradient_blocks.jl +++ b/src/components/gradient_waveforms/changing_gradient_blocks.jl @@ -36,7 +36,9 @@ end @defvar begin duration(cgb::ChangingGradient) = cgb.duration +end +@defvar gradient begin grad_start(cgb::ChangingGradient) = cgb.gradient_strength_start slew_rate(cgb::ChangingGradient) = cgb.slew_rate grad_end(cgb::ChangingGradient) = variables.grad_start(cgb) .+ variables.slew_rate(cgb) .* variables.duration(cgb) @@ -52,7 +54,7 @@ _mult(g1::AbstractVector, g2::AbstractVector) = g1 .* permutedims(g2) to_vec(cgb::ChangingGradient1D, g::VariableType) = cgb.orientation .* g to_vec(::ChangingGradient3D, g::AbstractVector) = g -@defvar begin +@defvar gradient begin function bmat_gradient(cgb::ChangingGradient, qstart::AbstractVector) # grad = (g1 * (duration - t) + g2 * t) / duration # = g1 + (g2 - g1) * t / duration diff --git a/src/components/gradient_waveforms/constant_gradient_blocks.jl b/src/components/gradient_waveforms/constant_gradient_blocks.jl index 0bc243a..397b703 100644 --- a/src/components/gradient_waveforms/constant_gradient_blocks.jl +++ b/src/components/gradient_waveforms/constant_gradient_blocks.jl @@ -30,8 +30,10 @@ struct ConstantGradient3D <: ConstantGradient{3} group :: Union{Symbol, Nothing} end -@defvar begin - duration(cgb::ConstantGradient) = cgb.duration + +@defvar duration(cgb::ConstantGradient) = cgb.duration + +@defvar gradient begin gradient_strength(cgb::ConstantGradient) = cgb.gradient_strength slew_rate(::ConstantGradient1D) = 0. slew_rate(::ConstantGradient3D) = zero(SVector{3, Float64}) diff --git a/src/components/gradient_waveforms/no_gradient_blocks.jl b/src/components/gradient_waveforms/no_gradient_blocks.jl index 659e672..cd0dbcc 100644 --- a/src/components/gradient_waveforms/no_gradient_blocks.jl +++ b/src/components/gradient_waveforms/no_gradient_blocks.jl @@ -24,7 +24,7 @@ end gradient_strength(nb::NoGradient, time::Number) = 0. end -@defvar begin +@defvar gradient begin bmat_gradient(::NoGradient) = 0. bmat_gradient(ngb::NoGradient, qstart::VariableType) = qstart^2 * duration(ngb) bmat_gradient(ngb::NoGradient, qstart::AbstractVector{<:VariableType}) = @. qstart * permutedims(qstart) * duration(ngb) diff --git a/src/components/instant_gradients.jl b/src/components/instant_gradients.jl index 99d81a2..441a6cb 100644 --- a/src/components/instant_gradients.jl +++ b/src/components/instant_gradients.jl @@ -42,7 +42,7 @@ struct InstantGradient1D <: InstantGradient{1} group :: Union{Nothing, Symbol} end -@defvar qval(ig::InstantGradient1D) = ig.qval +@defvar gradient qval(ig::InstantGradient1D) = ig.qval """ An [`InstantGradient`](@ref) with a variable orientation. @@ -61,12 +61,12 @@ function InstantGradient3D(; qval=[nothing, nothing, nothing], group=nothing, va return res end -@defvar qval(ig::InstantGradient3D) = ig.qvec +@defvar gradient qval(ig::InstantGradient3D) = ig.qvec variables.duration.f(::InstantGradient) = 0. variables.effective_time.f(::InstantGradient) = 0. -@defvar bmat_gradient(::InstantGradient, qstart=nothing) = zero(SMatrix{3, 3, Float64, 3}) +@defvar gradient bmat_gradient(::InstantGradient, qstart=nothing) = zero(SMatrix{3, 3, Float64, 3}) make_generic(ig::InstantGradient) = ig diff --git a/src/components/pulses/composite_pulses.jl b/src/components/pulses/composite_pulses.jl index 91f860c..459c77f 100644 --- a/src/components/pulses/composite_pulses.jl +++ b/src/components/pulses/composite_pulses.jl @@ -63,12 +63,13 @@ function wait_times(comp::CompositePulse) comp.pulse_time - (d[1:end-1] + d[2:end]) / 2 end -@defvar begin - duration(pulse::CompositePulse) = ( +@defvar duration(pulse::CompositePulse) = ( 0.5 * variables.duration(pulse.pulses[1]) + 0.5 * variables.duration(pulse.pulses[end]) + pulse.pulse_time * (length(pulse) - 1) ) + +@defvar begin flip_angle(pulse::CompositePulse) = sum(variables.flip_angle.(pulse.pulses)) effective_time(pulse::CompositePulse) = variables.duration(pulse) / 2 end diff --git a/src/components/pulses/constant_pulses.jl b/src/components/pulses/constant_pulses.jl index a88a4f0..ae9b7a0 100644 --- a/src/components/pulses/constant_pulses.jl +++ b/src/components/pulses/constant_pulses.jl @@ -38,18 +38,19 @@ function ConstantPulse(; amplitude=nothing, duration=nothing, phase=nothing, fre return res end -@defvar begin +@defvar duration(pulse::ConstantPulse) = pulse.duration +@defvar effective_time(pulse::ConstantPulse) = duration(pulse) / 2 + +@defvar pulse begin amplitude(pulse::ConstantPulse) = pulse.amplitude - duration(pulse::ConstantPulse) = pulse.duration phase(pulse::ConstantPulse) = pulse.phase frequency(pulse::ConstantPulse) = pulse.frequency amplitude(pulse::ConstantPulse, time::Number) = variables.amplitude(pulse) end -@defvar begin +@defvar pulse begin flip_angle(pulse::ConstantPulse) = amplitude(pulse) * duration(pulse) * 360 inverse_bandwidth(pulse::ConstantPulse) = duration(pulse) * 4 - effective_time(pulse::ConstantPulse) = duration(pulse) / 2 phase(pulse::ConstantPulse, time::Number) = variables.phase(pulse) + variables.frequency(pulse) * (time - variables.effective_time(pulse)) * 360. frequency(pulse::ConstantPulse, time::Number) = variables.frequency(pulse) diff --git a/src/components/pulses/generic_pulses.jl b/src/components/pulses/generic_pulses.jl index 90f18cc..9696194 100644 --- a/src/components/pulses/generic_pulses.jl +++ b/src/components/pulses/generic_pulses.jl @@ -68,10 +68,11 @@ end GenericPulse(pulse::RFPulseComponent, t1::Number, t2::Number) = GenericPulse(make_generic(pulse), t1, t2) -@defvar begin - duration(fp::GenericPulse) = maximum(fp.time) +@defvar duration(fp::GenericPulse) = maximum(fp.time) +@defvar effective_time(pulse::GenericPulse) = pulse.time[findmax(abs.(pulse.amplitude))] + +@defvar pulse begin amplitude(fp::GenericPulse) = maximum(abs.(fp.amplitude)) - effective_time(pulse::GenericPulse) = pulse.time[findmax(abs.(pulse.amplitude))] phase(pulse::GenericPulse) = pulse.phase[findmax(abs.(pulse.amplitude))[2]] flip_angle(pulse::GenericPulse) = sum(get_weights(pulse) .* pulse.amplitude) * 360 function time_halfway_flip(pulse::GenericPulse) @@ -99,7 +100,7 @@ for fn in (:amplitude, :phase) end -@defvar function frequency(gp::GenericPulse, time::Number) +@defvar pulse function frequency(gp::GenericPulse, time::Number) i2 = findfirst(t -> t > time, gp.time) if isnothing(i2) @assert time ≈ gp.time[end] diff --git a/src/components/pulses/sinc_pulses.jl b/src/components/pulses/sinc_pulses.jl index a2b630c..41e9514 100644 --- a/src/components/pulses/sinc_pulses.jl +++ b/src/components/pulses/sinc_pulses.jl @@ -79,13 +79,13 @@ function integral_nzero(Nzeros, apodise) return quadgk(f, 0, Nzeros)[1] end -@defvar begin +@defvar pulse begin amplitude(pulse::SincPulse) = pulse.amplitude N_left(pulse::SincPulse) = pulse.Nzeros[1] N_right(pulse::SincPulse) = pulse.Nzeros[2] end -@defvar begin +@defvar pulse begin phase(pulse::SincPulse) = pulse.phase frequency(pulse::SincPulse) = pulse.frequency lobe_duration(pulse::SincPulse) = pulse.lobe_duration diff --git a/src/components/readouts/ADCs.jl b/src/components/readouts/ADCs.jl index 2f1a234..430fc49 100644 --- a/src/components/readouts/ADCs.jl +++ b/src/components/readouts/ADCs.jl @@ -48,17 +48,17 @@ function ADC(; resolution=nothing, dwell_time=nothing, time_to_center=nothing, c return res end -@defvar begin +@defvar readout begin oversample(adc::ADC) = adc.oversample dwell_time(adc::ADC) = adc.dwell_time time_to_center(adc::ADC) = adc.time_to_center resolution(adc::ADC) = adc.resolution end -@defvar nsamples(adc::ADC) = resolution(adc) * oversample(adc) +@defvar readout nsamples(adc::ADC) = resolution(adc) * oversample(adc) +@defvar readout_times(adc::ADC) = ((1:Int(nsamples(adc))) .- 0.5) .* dwell_time(adc) @defvar begin - readout_times(adc::ADC) = ((1:Int(nsamples(adc))) .- 0.5) .* dwell_time(adc) duration(adc::ADC) = nsamples(adc) * dwell_time(adc) effective_time(adc::ADC) = time_to_center(adc) end diff --git a/src/containers/building_blocks.jl b/src/containers/building_blocks.jl index e46d3ea..3b67ff9 100644 --- a/src/containers/building_blocks.jl +++ b/src/containers/building_blocks.jl @@ -8,7 +8,7 @@ import StaticArrays: SVector import ..Abstract: ContainerBlock, start_time, readout_times, end_time, iter import ...BuildSequences: global_model import ...Components: BaseComponent, GradientWaveform, EventComponent, NoGradient, ChangingGradient, ConstantGradient, split_gradient, RFPulseComponent, ReadoutComponent, InstantGradient, edge_times -import ...Variables: VariableType, make_generic, get_pulse, get_readout, scanner_constraints!, get_gradient, gradient_orientation, variables, @defvar +import ...Variables: VariableType, make_generic, get_pulse, get_readout, scanner_constraints!, get_gradient, gradient_orientation, variables, @defvar, get_free_variable """ Basic BuildingBlock, which can consist of a gradient waveforms with any number of RF pulses/readouts overlaid diff --git a/src/parts/epi_readouts.jl b/src/parts/epi_readouts.jl index 92fb34c..de8d2e7 100644 --- a/src/parts/epi_readouts.jl +++ b/src/parts/epi_readouts.jl @@ -32,7 +32,7 @@ struct EPIReadout{N} <: BaseSequence{N} ky_lines :: AbstractVector{<:Integer} end -function EPIReadout(; resolution::AbstractVector{<:Integer}, recenter=false, group=:FOV, ky_lines=nothing, variables...) +function EPIReadout(; resolution::AbstractVector{<:Integer}, recenter=false, group=:FOV, ky_lines=nothing, vars...) if length(resolution) != 2 error("EPIReadout expects the image resolution in the x- and y-direction.") end @@ -49,15 +49,15 @@ function EPIReadout(; resolution::AbstractVector{<:Integer}, recenter=false, gro get_free_variable(nothing), ky_lines ) - apply_simple_constraint!(variables.qval3(res.start_gradient), VariableType[-variables.qval(pos)/2, ky_lines[1] * res.ky_step, 0.]) + apply_simple_constraint!(variables.qval(res.start_gradient), VariableType[-variables.qval(pos)/2, ky_lines[1] * res.ky_step, 0.]) if recenter sign = isodd(length(ky_lines)) ? -1 : 1 - apply_simple_constraint!(variables.qval3(res.recenter_gradient), VariableType[sign * variables.qval(pos)/2, -ky_lines[end] * res.ky_step, 0.]) + apply_simple_constraint!(variables.qval(res.recenter_gradient), VariableType[sign * variables.qval(pos)/2, -ky_lines[end] * res.ky_step, 0.]) end for shift in unique(ky_lines[2:end] - ky_lines[1:end-1]) res.blips[shift] = Trapezoid(orientation=[0, shift > 0 ? 1 : -1, 0], group=group, qval=abs(shift) * res.ky_step) end - set_simple_constraints!(res, variables) + set_simple_constraints!(res, vars) return res end -- GitLab