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

Also apply esc to variable definition body

parent a5a4fe20
No related branches found
No related tags found
1 merge request!2Define variables through new @defvar macro
Showing
with 68 additions and 53 deletions
......@@ -34,17 +34,16 @@ struct ChangingGradient3D <: ChangingGradient{3}
group :: Union{Nothing, Symbol}
end
@defvar begin
duration(cgb::ChangingGradient) = cgb.duration
grad_start(cgb::ChangingGradient) = cgb.gradient_strength_start
slew_rate(cgb::ChangingGradient) = cgb.slew_rate
grad_end(cgb::ChangingGradient) = grad_start(cgb) .+ slew_rate(cgb) .* duration(cgb)
gradient_strength(cgb::ChangingGradient) = max.(grad_start(cgb), grad_end(cgb))
qval(cgb::ChangingGradient) = (grad_start(cgb) .+ grad_end(cgb)) .* (duration(cgb) * π)
grad_end(cgb::ChangingGradient) = variables.grad_start(cgb) .+ variables.slew_rate(cgb) .* variables.duration(cgb)
gradient_strength(cgb::ChangingGradient) = max.(variables.grad_start(cgb), variables.grad_end(cgb))
qval(cgb::ChangingGradient) = (variables.grad_start(cgb) .+ variables.grad_end(cgb)) .* (variables.duration(cgb) * π)
gradient_strength(cgb::ChangingGradient, time::Number) = slew_rate(cgb) .* time .+ grad_start(cgb)
gradient_strength(cgb::ChangingGradient, time::Number) = variables.slew_rate(cgb) .* time .+ variables.grad_start(cgb)
end
_mult(g1::VariableType, g2::VariableType) = g1 * g2
......@@ -69,7 +68,7 @@ to_vec(::ChangingGradient3D, g::AbstractVector) = g
return (
_mult(qstart, qstart) .* duration(cgb) .+
duration(cgb)^2 .* _mult(qstart, grad_aver) .* 2π ./ 3 .+
bmat_gradient(cgb)
variables.bmat_gradient(cgb)
)
end
......
......@@ -35,10 +35,10 @@ end
gradient_strength(cgb::ConstantGradient) = cgb.gradient_strength
slew_rate(::ConstantGradient1D) = 0.
slew_rate(::ConstantGradient3D) = zero(SVector{3, Float64})
qval(cgb::ConstantGradient1D) = duration(cgb) * gradient_strength(cgb) * 2π
qval(cgb::ConstantGradient3D) = duration(cgb) .* gradient_strength(cgb) .* 2π
qval(cgb::ConstantGradient1D) = variables.duration(cgb) * variables.gradient_strength(cgb) * 2π
qval(cgb::ConstantGradient3D) = variables.duration(cgb) .* variables.gradient_strength(cgb) .* 2π
gradient_strength(cgb::ConstantGradient, time::Number) = gradient_strength(cgb)
gradient_strength(cgb::ConstantGradient, time::Number) = variables.gradient_strength(cgb)
end
_mult(g1::VariableType, g2::VariableType) = g1 * g2
......@@ -62,7 +62,7 @@ to_vec(::ConstantGradient3D, g::AbstractVector) = g
return (
_mult(qstart, qstart) .* duration(cgb) .+
_mult(qstart, grad) .* duration(cgb)^2 .+
bmat_gradient(cgb)
variables.bmat_gradient(cgb)
)
end
end
......
......@@ -22,7 +22,9 @@ end
@defvar begin
duration(ngb::NoGradient) = ngb.duration
gradient_strength(nb::NoGradient, time::Number) = 0.
end
@defvar 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)
......
......@@ -65,12 +65,12 @@ end
@defvar begin
duration(pulse::CompositePulse) = (
0.5 * duration(pulse.pulses[1]) +
0.5 * duration(pulse.pulses[end]) +
0.5 * variables.duration(pulse.pulses[1]) +
0.5 * variables.duration(pulse.pulses[end]) +
pulse.pulse_time * (length(pulse) - 1)
)
flip_angle(pulse::CompositePulse) = sum(flip_angle.(pulse.pulses))
effective_time(pulse::CompositePulse) = duration(pulse) / 2
flip_angle(pulse::CompositePulse) = sum(variables.flip_angle.(pulse.pulses))
effective_time(pulse::CompositePulse) = variables.duration(pulse) / 2
end
......
......@@ -43,13 +43,16 @@ end
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
flip_angle(pulse::ConstantPulse) = amplitude(pulse) * duration(pulse) * 360
inverse_bandwidth(pulse::ConstantPulse) = duration(pulse) * 4
effective_time(pulse::ConstantPulse) = duration(pulse) / 2
amplitude(pulse::ConstantPulse, time::Number) = amplitude(pulse)
phase(pulse::ConstantPulse, time::Number) = phase(pulse) + frequency(pulse) * (time - effective_time(pulse)) * 360.
frequency(pulse::ConstantPulse, time::Number) = frequency(pulse)
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)
end
function make_generic(block::ConstantPulse)
......
......@@ -83,17 +83,25 @@ end
amplitude(pulse::SincPulse) = pulse.amplitude
N_left(pulse::SincPulse) = pulse.Nzeros[1]
N_right(pulse::SincPulse) = pulse.Nzeros[2]
duration(pulse::SincPulse) = (N_left(pulse) + N_right(pulse)) * lobe_duration(pulse)
end
@defvar begin
phase(pulse::SincPulse) = pulse.phase
frequency(pulse::SincPulse) = pulse.frequency
flip_angle(pulse::SincPulse) = (pulse.norm_flip_angle[1] + pulse.norm_flip_angle[2]) * amplitude(pulse) * lobe_duration(pulse) * 360
lobe_duration(pulse::SincPulse) = pulse.lobe_duration
end
@defvar begin
duration(pulse::SincPulse) = (N_left(pulse) + N_right(pulse)) * lobe_duration(pulse)
flip_angle(pulse::SincPulse) = (pulse.norm_flip_angle[1] + pulse.norm_flip_angle[2]) * amplitude(pulse) * lobe_duration(pulse) * 360
inverse_bandwidth(pulse::SincPulse) = lobe_duration(pulse)
effective_time(pulse::SincPulse) = N_left(pulse) * lobe_duration(pulse)
end
amplitude(pulse::SincPulse, time::Number) = amplitude(pulse) * normalised_function(abs((time - effective_time(pulse))) / lobe_duration(pulse), N_left(pulse), N_right(pulse); apodise=pulse.apodise)
phase(pulse::SincPulse, time::Number) = phase(pulse) + frequency(pulse) * (time - effective_time(pulse)) * 360.
frequency(pulse::SincPulse, time::Number) = frequency(pulse)
@defvar begin
amplitude(pulse::SincPulse, time::Number) = variables.amplitude(pulse) * normalised_function(abs((time - effective_time(pulse))) / lobe_duration(pulse), N_left(pulse), N_right(pulse); apodise=pulse.apodise)
phase(pulse::SincPulse, time::Number) = variables.phase(pulse) + variables.frequency(pulse) * (time - effective_time(pulse)) * 360.
frequency(pulse::SincPulse, time::Number) = variables.frequency(pulse)
end
function make_generic(block::SincPulse)
......
......@@ -49,16 +49,20 @@ function ADC(; resolution=nothing, dwell_time=nothing, time_to_center=nothing, c
end
@defvar begin
readout_times(adc::ADC) = ((1:Int(nsamples(adc))) .- 0.5) .* dwell_time(adc)
oversample(adc::ADC) = adc.oversample
nsamples(adc::ADC) = resolution(adc) * oversample(adc)
dwell_time(adc::ADC) = adc.dwell_time
duration(adc::ADC) = nsamples(adc) * dwell_time(adc)
time_to_center(adc::ADC) = adc.time_to_center
effective_time(adc::ADC) = time_to_center(adc)
resolution(adc::ADC) = adc.resolution
end
@defvar nsamples(adc::ADC) = resolution(adc) * oversample(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
function fixed(adc::ADC)
# round nsamples during fixing
r = Int(round(value(resolution(adc)), RoundNearest))
......
......@@ -34,8 +34,8 @@ end_time(block::AbstractBlock) = duration(block)
end_time(block::Tuple{<:VariableType, <:AbstractBlock}) = duration(block[2])
@defvar begin
effective_time(container::ContainerBlock, index, indices...) = start_time(container, index) + effective_time(container[index], indices...)
effective_time(block::Tuple{<:VariableType, <:AbstractBlock}) = block[1] + effective_time(block[2])
effective_time(container::ContainerBlock, index, indices...) = start_time(container, index) + variables.effective_time(container[index], indices...)
effective_time(block::Tuple{<:VariableType, <:AbstractBlock}) = block[1] + variables.effective_time(block[2])
end
"""
effective_time(container, indices...)
......
......@@ -23,7 +23,7 @@ AlternativeBlocks(name::Symbol, options_vector::AbstractVector) = AlternativeBlo
Base.getindex(alt::AlternativeBlocks, index) = alt.options[index]
Base.length(alt::AlternativeBlocks) = length(alt.options)
@defvar duration(alt::AlternativeBlocks) = maximum(duration.(values(alt.options)))
@defvar duration(alt::AlternativeBlocks) = maximum(variables.duration.(values(alt.options)))
"""
match_blocks!(alternatives, function)
......
......@@ -104,7 +104,7 @@ repetition_time(bs::BaseSequence) = duration(bs)
@defvar begin
duration(bs::BaseSequence{0}) = 0.
duration(bs::BaseSequence) = sum(duration.(bs); init=0.)
duration(bs::BaseSequence) = sum(variables.duration.(bs); init=0.)
end
function edge_times(seq::BaseSequence; tol=1e-6)
......
......@@ -142,7 +142,7 @@ function start_time(building_block::BaseBuildingBlock, index)
error("Building block with index '$index' not found")
end
@defvar duration(bb::BaseBuildingBlock) = sum([duration(wv) for (_, wv) in waveform_sequence(bb)])
@defvar duration(bb::BaseBuildingBlock) = sum([variables.duration(wv) for (_, wv) in waveform_sequence(bb)])
# Pathway support
"""
......@@ -195,18 +195,18 @@ end
if (!isnothing(index1)) && (index1 == index2)
return 0.
end
res = sum([qval(wv) for (_, wv) in waveform_sequence(bb, index1, index2)])
res = sum([variables.qval(wv) for (_, wv) in waveform_sequence(bb, index1, index2)])
t1 = isnothing(index1) ? 0. : start_time(bb, index1)
t2 = isnothing(index2) ? duration(bb) : start_time(bb, index2)
for (key, event) in events(bb)
if event isa InstantGradient && (t1 <= start_time(bb, key) <= t2)
res = res .+ qval(event)
res = res .+ variables.qval(event)
end
end
return res
end
qval(bb::BaseBuildingBlock) = qval(bb, nothing, nothing)
qval(bb::BaseBuildingBlock) = variables.qval(bb, nothing, nothing)
function bmat_gradient(bb::BaseBuildingBlock, qstart, index1, index2)
if (!isnothing(index1)) && (index1 == index2)
......@@ -216,12 +216,12 @@ end
qcurrent = Vector{VariableType}(qstart)
for (_, part) in waveform_sequence(bb, index1, index2)
result = result .+ bmat_gradient(part, qcurrent)
result = result .+ variables.bmat_gradient(part, qcurrent)
qcurrent = qcurrent .+ qval3(part, qcurrent)
end
return result
end
bmat_gradient(bb::BaseBuildingBlock, qstart) = bmat_gradient(bb, qstart, nothing, nothing)
bmat_gradient(bb::BaseBuildingBlock, qstart) = variables.bmat_gradient(bb, qstart, nothing, nothing)
end
"""
......@@ -277,7 +277,7 @@ end
@defvar function gradient_strength(bb::BaseBuildingBlock, time::Number)
(grad, time) = get_gradient(bb, time)
return gradient_strength(grad, time)
return variables.gradient_strength(grad, time)
end
"""
......@@ -363,7 +363,7 @@ end
error("BuildingBlock contains multiple RF pulse or readout events, so `effective_time` is not defined.")
end
index = index[1]
return effective_time(bb, index)
return variables.effective_time(bb, index)
end
"""
......
......@@ -112,9 +112,12 @@ Base.getindex(spoilt::SpoiltSliceSelect, ::Val{:fall2}) = ChangingGradient(slew_
rise_time(spoilt::SpoiltSliceSelect) = (spoilt.rise_time1, spoilt.fall_time2 - spoilt.diff_time)
flat_time(spoilt::SpoiltSliceSelect) = (spoilt.flat_time1, spoilt.flat_time2)
fall_time(spoilt::SpoiltSliceSelect) = (spoilt.rise_time1 - spoilt.diff_time, spoilt.fall_time2)
duration(spoilt::SpoiltSliceSelect) = sum(rise_time(spoilt)) + sum(flat_time(spoilt)) + sum(flat_time(spoilt)) + duration(spoilt.pulse)
slew_rate(spoilt::SpoiltSliceSelect) = spoilt.slew_rate
inverse_slice_thickness(spoilt::SpoiltSliceSelect) = spoilt.slew_rate * spoilt.diff_time * duration(spoilt.pulse) * 1e3
end
@defvar begin
duration(spoilt::SpoiltSliceSelect) = sum(rise_time(spoilt)) + sum(flat_time(spoilt)) + sum(flat_time(spoilt)) + variables.duration(spoilt.pulse)
inverse_slice_thickness(spoilt::SpoiltSliceSelect) = slew_rate(spoilt) * spoilt.diff_time * variables.duration(spoilt.pulse) * 1e3
gradient_strength(spoilt::SpoiltSliceSelect) = slew_rate(spoilt) * max(spoilt.rise_time1, spoilt.fall_time2)
end
......
......@@ -109,14 +109,17 @@ get_group(pg::BaseTrapezoid) = get_group(get_gradient(pg))
@defvar begin
rise_time(pg::Trapezoid) = pg.rise_time
flat_time(pg::Trapezoid) = pg.flat_time
gradient_strength(g::Trapezoid) = slew_rate(g) .* rise_time(g)
slew_rate(g::Trapezoid) = g.slew_rate
diffusion_time(g::Trapezoid) = rise_time(g) + flat_time(g)
duration(g::BaseTrapezoid) = 2 * rise_time(g) + flat_time(g)
end
qval(g::BaseTrapezoid, ::Nothing, ::Nothing) = δ(g) .* gradient_strength(g) .* 2π
@defvar begin
gradient_strength(g::Trapezoid) = slew_rate(g) .* rise_time(g)
δ(g::Trapezoid) = rise_time(g) + flat_time(g)
duration(g::BaseTrapezoid) = 2 * rise_time(g) + flat_time(g)
end
@defvar qval(g::BaseTrapezoid, ::Nothing, ::Nothing) = variables.δ(g) .* gradient_strength(g) .* 2π
adjustable(::BaseTrapezoid) = :gradient
function adjust_internal(trap::Trapezoid1D; orientation=nothing, scale=1., rotation=nothing)
......
......@@ -95,6 +95,7 @@ variables = _Variables(Dict{Symbol, AnyVariable}())
Base.getindex(v::_Variables, i::Symbol) = getfield(v, :variables)[i]
Base.keys(v::_Variables) = keys(getfield(v, :variables))
Base.values(v::_Variables) = values(getfield(v, :variables))
Base.propertynames(v::_Variables) = Tuple(keys(getfield(v, :variables)))
......@@ -441,16 +442,8 @@ function scanner_constraints!(bb::AbstractBlock)
value = nothing
try
value = f(bb)
catch e
continue
continue
else
rethrow()
end
catch
continue
else
rethrow()
end
end
if value isa AbstractVector
for v in value
......
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