Skip to content
Snippets Groups Projects
Unverified Commit 79cefb01 authored by Michiel Cottaar's avatar Michiel Cottaar
Browse files

Assign type to variables

parent 6909c026
No related branches found
No related tags found
1 merge request!2Define variables through new @defvar macro
...@@ -36,7 +36,9 @@ end ...@@ -36,7 +36,9 @@ end
@defvar begin @defvar begin
duration(cgb::ChangingGradient) = cgb.duration duration(cgb::ChangingGradient) = cgb.duration
end
@defvar gradient begin
grad_start(cgb::ChangingGradient) = cgb.gradient_strength_start grad_start(cgb::ChangingGradient) = cgb.gradient_strength_start
slew_rate(cgb::ChangingGradient) = cgb.slew_rate slew_rate(cgb::ChangingGradient) = cgb.slew_rate
grad_end(cgb::ChangingGradient) = variables.grad_start(cgb) .+ variables.slew_rate(cgb) .* variables.duration(cgb) 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) ...@@ -52,7 +54,7 @@ _mult(g1::AbstractVector, g2::AbstractVector) = g1 .* permutedims(g2)
to_vec(cgb::ChangingGradient1D, g::VariableType) = cgb.orientation .* g to_vec(cgb::ChangingGradient1D, g::VariableType) = cgb.orientation .* g
to_vec(::ChangingGradient3D, g::AbstractVector) = g to_vec(::ChangingGradient3D, g::AbstractVector) = g
@defvar begin @defvar gradient begin
function bmat_gradient(cgb::ChangingGradient, qstart::AbstractVector) function bmat_gradient(cgb::ChangingGradient, qstart::AbstractVector)
# grad = (g1 * (duration - t) + g2 * t) / duration # grad = (g1 * (duration - t) + g2 * t) / duration
# = g1 + (g2 - g1) * t / duration # = g1 + (g2 - g1) * t / duration
......
...@@ -30,8 +30,10 @@ struct ConstantGradient3D <: ConstantGradient{3} ...@@ -30,8 +30,10 @@ struct ConstantGradient3D <: ConstantGradient{3}
group :: Union{Symbol, Nothing} group :: Union{Symbol, Nothing}
end end
@defvar begin
duration(cgb::ConstantGradient) = cgb.duration @defvar duration(cgb::ConstantGradient) = cgb.duration
@defvar gradient begin
gradient_strength(cgb::ConstantGradient) = cgb.gradient_strength gradient_strength(cgb::ConstantGradient) = cgb.gradient_strength
slew_rate(::ConstantGradient1D) = 0. slew_rate(::ConstantGradient1D) = 0.
slew_rate(::ConstantGradient3D) = zero(SVector{3, Float64}) slew_rate(::ConstantGradient3D) = zero(SVector{3, Float64})
......
...@@ -24,7 +24,7 @@ end ...@@ -24,7 +24,7 @@ end
gradient_strength(nb::NoGradient, time::Number) = 0. gradient_strength(nb::NoGradient, time::Number) = 0.
end end
@defvar begin @defvar gradient begin
bmat_gradient(::NoGradient) = 0. bmat_gradient(::NoGradient) = 0.
bmat_gradient(ngb::NoGradient, qstart::VariableType) = qstart^2 * duration(ngb) bmat_gradient(ngb::NoGradient, qstart::VariableType) = qstart^2 * duration(ngb)
bmat_gradient(ngb::NoGradient, qstart::AbstractVector{<:VariableType}) = @. qstart * permutedims(qstart) * duration(ngb) bmat_gradient(ngb::NoGradient, qstart::AbstractVector{<:VariableType}) = @. qstart * permutedims(qstart) * duration(ngb)
......
...@@ -42,7 +42,7 @@ struct InstantGradient1D <: InstantGradient{1} ...@@ -42,7 +42,7 @@ struct InstantGradient1D <: InstantGradient{1}
group :: Union{Nothing, Symbol} group :: Union{Nothing, Symbol}
end end
@defvar qval(ig::InstantGradient1D) = ig.qval @defvar gradient qval(ig::InstantGradient1D) = ig.qval
""" """
An [`InstantGradient`](@ref) with a variable orientation. An [`InstantGradient`](@ref) with a variable orientation.
...@@ -61,12 +61,12 @@ function InstantGradient3D(; qval=[nothing, nothing, nothing], group=nothing, va ...@@ -61,12 +61,12 @@ function InstantGradient3D(; qval=[nothing, nothing, nothing], group=nothing, va
return res return res
end end
@defvar qval(ig::InstantGradient3D) = ig.qvec @defvar gradient qval(ig::InstantGradient3D) = ig.qvec
variables.duration.f(::InstantGradient) = 0. variables.duration.f(::InstantGradient) = 0.
variables.effective_time.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 make_generic(ig::InstantGradient) = ig
......
...@@ -63,12 +63,13 @@ function wait_times(comp::CompositePulse) ...@@ -63,12 +63,13 @@ function wait_times(comp::CompositePulse)
comp.pulse_time - (d[1:end-1] + d[2:end]) / 2 comp.pulse_time - (d[1:end-1] + d[2:end]) / 2
end end
@defvar begin @defvar duration(pulse::CompositePulse) = (
duration(pulse::CompositePulse) = (
0.5 * variables.duration(pulse.pulses[1]) + 0.5 * variables.duration(pulse.pulses[1]) +
0.5 * variables.duration(pulse.pulses[end]) + 0.5 * variables.duration(pulse.pulses[end]) +
pulse.pulse_time * (length(pulse) - 1) pulse.pulse_time * (length(pulse) - 1)
) )
@defvar begin
flip_angle(pulse::CompositePulse) = sum(variables.flip_angle.(pulse.pulses)) flip_angle(pulse::CompositePulse) = sum(variables.flip_angle.(pulse.pulses))
effective_time(pulse::CompositePulse) = variables.duration(pulse) / 2 effective_time(pulse::CompositePulse) = variables.duration(pulse) / 2
end end
......
...@@ -38,18 +38,19 @@ function ConstantPulse(; amplitude=nothing, duration=nothing, phase=nothing, fre ...@@ -38,18 +38,19 @@ function ConstantPulse(; amplitude=nothing, duration=nothing, phase=nothing, fre
return res return res
end 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 amplitude(pulse::ConstantPulse) = pulse.amplitude
duration(pulse::ConstantPulse) = pulse.duration
phase(pulse::ConstantPulse) = pulse.phase phase(pulse::ConstantPulse) = pulse.phase
frequency(pulse::ConstantPulse) = pulse.frequency frequency(pulse::ConstantPulse) = pulse.frequency
amplitude(pulse::ConstantPulse, time::Number) = variables.amplitude(pulse) amplitude(pulse::ConstantPulse, time::Number) = variables.amplitude(pulse)
end end
@defvar begin @defvar pulse begin
flip_angle(pulse::ConstantPulse) = amplitude(pulse) * duration(pulse) * 360 flip_angle(pulse::ConstantPulse) = amplitude(pulse) * duration(pulse) * 360
inverse_bandwidth(pulse::ConstantPulse) = duration(pulse) * 4 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. 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) frequency(pulse::ConstantPulse, time::Number) = variables.frequency(pulse)
......
...@@ -68,10 +68,11 @@ end ...@@ -68,10 +68,11 @@ end
GenericPulse(pulse::RFPulseComponent, t1::Number, t2::Number) = GenericPulse(make_generic(pulse), t1, t2) GenericPulse(pulse::RFPulseComponent, t1::Number, t2::Number) = GenericPulse(make_generic(pulse), t1, t2)
@defvar begin @defvar duration(fp::GenericPulse) = maximum(fp.time)
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)) 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]] phase(pulse::GenericPulse) = pulse.phase[findmax(abs.(pulse.amplitude))[2]]
flip_angle(pulse::GenericPulse) = sum(get_weights(pulse) .* pulse.amplitude) * 360 flip_angle(pulse::GenericPulse) = sum(get_weights(pulse) .* pulse.amplitude) * 360
function time_halfway_flip(pulse::GenericPulse) function time_halfway_flip(pulse::GenericPulse)
...@@ -99,7 +100,7 @@ for fn in (:amplitude, :phase) ...@@ -99,7 +100,7 @@ for fn in (:amplitude, :phase)
end end
@defvar function frequency(gp::GenericPulse, time::Number) @defvar pulse function frequency(gp::GenericPulse, time::Number)
i2 = findfirst(t -> t > time, gp.time) i2 = findfirst(t -> t > time, gp.time)
if isnothing(i2) if isnothing(i2)
@assert time gp.time[end] @assert time gp.time[end]
......
...@@ -79,13 +79,13 @@ function integral_nzero(Nzeros, apodise) ...@@ -79,13 +79,13 @@ function integral_nzero(Nzeros, apodise)
return quadgk(f, 0, Nzeros)[1] return quadgk(f, 0, Nzeros)[1]
end end
@defvar begin @defvar pulse begin
amplitude(pulse::SincPulse) = pulse.amplitude amplitude(pulse::SincPulse) = pulse.amplitude
N_left(pulse::SincPulse) = pulse.Nzeros[1] N_left(pulse::SincPulse) = pulse.Nzeros[1]
N_right(pulse::SincPulse) = pulse.Nzeros[2] N_right(pulse::SincPulse) = pulse.Nzeros[2]
end end
@defvar begin @defvar pulse begin
phase(pulse::SincPulse) = pulse.phase phase(pulse::SincPulse) = pulse.phase
frequency(pulse::SincPulse) = pulse.frequency frequency(pulse::SincPulse) = pulse.frequency
lobe_duration(pulse::SincPulse) = pulse.lobe_duration lobe_duration(pulse::SincPulse) = pulse.lobe_duration
......
...@@ -48,17 +48,17 @@ function ADC(; resolution=nothing, dwell_time=nothing, time_to_center=nothing, c ...@@ -48,17 +48,17 @@ function ADC(; resolution=nothing, dwell_time=nothing, time_to_center=nothing, c
return res return res
end end
@defvar begin @defvar readout begin
oversample(adc::ADC) = adc.oversample oversample(adc::ADC) = adc.oversample
dwell_time(adc::ADC) = adc.dwell_time dwell_time(adc::ADC) = adc.dwell_time
time_to_center(adc::ADC) = adc.time_to_center time_to_center(adc::ADC) = adc.time_to_center
resolution(adc::ADC) = adc.resolution resolution(adc::ADC) = adc.resolution
end 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 @defvar begin
readout_times(adc::ADC) = ((1:Int(nsamples(adc))) .- 0.5) .* dwell_time(adc)
duration(adc::ADC) = nsamples(adc) * dwell_time(adc) duration(adc::ADC) = nsamples(adc) * dwell_time(adc)
effective_time(adc::ADC) = time_to_center(adc) effective_time(adc::ADC) = time_to_center(adc)
end end
......
...@@ -8,7 +8,7 @@ import StaticArrays: SVector ...@@ -8,7 +8,7 @@ import StaticArrays: SVector
import ..Abstract: ContainerBlock, start_time, readout_times, end_time, iter import ..Abstract: ContainerBlock, start_time, readout_times, end_time, iter
import ...BuildSequences: global_model import ...BuildSequences: global_model
import ...Components: BaseComponent, GradientWaveform, EventComponent, NoGradient, ChangingGradient, ConstantGradient, split_gradient, RFPulseComponent, ReadoutComponent, InstantGradient, edge_times 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 Basic BuildingBlock, which can consist of a gradient waveforms with any number of RF pulses/readouts overlaid
......
...@@ -32,7 +32,7 @@ struct EPIReadout{N} <: BaseSequence{N} ...@@ -32,7 +32,7 @@ struct EPIReadout{N} <: BaseSequence{N}
ky_lines :: AbstractVector{<:Integer} ky_lines :: AbstractVector{<:Integer}
end 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 if length(resolution) != 2
error("EPIReadout expects the image resolution in the x- and y-direction.") error("EPIReadout expects the image resolution in the x- and y-direction.")
end end
...@@ -49,15 +49,15 @@ function EPIReadout(; resolution::AbstractVector{<:Integer}, recenter=false, gro ...@@ -49,15 +49,15 @@ function EPIReadout(; resolution::AbstractVector{<:Integer}, recenter=false, gro
get_free_variable(nothing), get_free_variable(nothing),
ky_lines 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 if recenter
sign = isodd(length(ky_lines)) ? -1 : 1 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 end
for shift in unique(ky_lines[2:end] - ky_lines[1:end-1]) 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) res.blips[shift] = Trapezoid(orientation=[0, shift > 0 ? 1 : -1, 0], group=group, qval=abs(shift) * res.ky_step)
end end
set_simple_constraints!(res, variables) set_simple_constraints!(res, vars)
return res return res
end end
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment