From 201ce04e6d1a067e7b22dc96d31e96d92f7c9551 Mon Sep 17 00:00:00 2001 From: Michiel Cottaar <MichielCottaar@protonmail.com> Date: Fri, 24 May 2024 16:45:12 +0100 Subject: [PATCH] Also apply esc to variable definition body --- .../changing_gradient_blocks.jl | 11 +++++------ .../constant_gradient_blocks.jl | 8 ++++---- .../gradient_waveforms/no_gradient_blocks.jl | 2 ++ src/components/pulses/composite_pulses.jl | 8 ++++---- src/components/pulses/constant_pulses.jl | 9 ++++++--- src/components/pulses/sinc_pulses.jl | 18 +++++++++++++----- src/components/readouts/ADCs.jl | 12 ++++++++---- src/containers/abstract.jl | 4 ++-- src/containers/alternatives.jl | 2 +- src/containers/base_sequences.jl | 2 +- src/containers/building_blocks.jl | 16 ++++++++-------- src/parts/spoilt_slice_selects.jl | 7 +++++-- src/parts/trapezoids.jl | 11 +++++++---- src/variables.jl | 11 ++--------- 14 files changed, 68 insertions(+), 53 deletions(-) diff --git a/src/components/gradient_waveforms/changing_gradient_blocks.jl b/src/components/gradient_waveforms/changing_gradient_blocks.jl index 7748a06..b831687 100644 --- a/src/components/gradient_waveforms/changing_gradient_blocks.jl +++ b/src/components/gradient_waveforms/changing_gradient_blocks.jl @@ -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 diff --git a/src/components/gradient_waveforms/constant_gradient_blocks.jl b/src/components/gradient_waveforms/constant_gradient_blocks.jl index 72559b0..0bc243a 100644 --- a/src/components/gradient_waveforms/constant_gradient_blocks.jl +++ b/src/components/gradient_waveforms/constant_gradient_blocks.jl @@ -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 diff --git a/src/components/gradient_waveforms/no_gradient_blocks.jl b/src/components/gradient_waveforms/no_gradient_blocks.jl index 93abce4..659e672 100644 --- a/src/components/gradient_waveforms/no_gradient_blocks.jl +++ b/src/components/gradient_waveforms/no_gradient_blocks.jl @@ -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) diff --git a/src/components/pulses/composite_pulses.jl b/src/components/pulses/composite_pulses.jl index 53d9778..91f860c 100644 --- a/src/components/pulses/composite_pulses.jl +++ b/src/components/pulses/composite_pulses.jl @@ -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 diff --git a/src/components/pulses/constant_pulses.jl b/src/components/pulses/constant_pulses.jl index dfe427e..a88a4f0 100644 --- a/src/components/pulses/constant_pulses.jl +++ b/src/components/pulses/constant_pulses.jl @@ -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) diff --git a/src/components/pulses/sinc_pulses.jl b/src/components/pulses/sinc_pulses.jl index a07d5a8..a2b630c 100644 --- a/src/components/pulses/sinc_pulses.jl +++ b/src/components/pulses/sinc_pulses.jl @@ -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) diff --git a/src/components/readouts/ADCs.jl b/src/components/readouts/ADCs.jl index 1ed5e5b..2f1a234 100644 --- a/src/components/readouts/ADCs.jl +++ b/src/components/readouts/ADCs.jl @@ -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)) diff --git a/src/containers/abstract.jl b/src/containers/abstract.jl index d4ed89e..ea301a8 100644 --- a/src/containers/abstract.jl +++ b/src/containers/abstract.jl @@ -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...) diff --git a/src/containers/alternatives.jl b/src/containers/alternatives.jl index 0c75bbe..731042b 100644 --- a/src/containers/alternatives.jl +++ b/src/containers/alternatives.jl @@ -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) diff --git a/src/containers/base_sequences.jl b/src/containers/base_sequences.jl index 5f6d45a..7f80bef 100644 --- a/src/containers/base_sequences.jl +++ b/src/containers/base_sequences.jl @@ -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) diff --git a/src/containers/building_blocks.jl b/src/containers/building_blocks.jl index 8849341..e46d3ea 100644 --- a/src/containers/building_blocks.jl +++ b/src/containers/building_blocks.jl @@ -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 """ diff --git a/src/parts/spoilt_slice_selects.jl b/src/parts/spoilt_slice_selects.jl index ebaa4e3..fd70b36 100644 --- a/src/parts/spoilt_slice_selects.jl +++ b/src/parts/spoilt_slice_selects.jl @@ -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 diff --git a/src/parts/trapezoids.jl b/src/parts/trapezoids.jl index 0059b18..7fc7aa6 100644 --- a/src/parts/trapezoids.jl +++ b/src/parts/trapezoids.jl @@ -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) diff --git a/src/variables.jl b/src/variables.jl index 7220259..20a6541 100644 --- a/src/variables.jl +++ b/src/variables.jl @@ -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 -- GitLab