From 9c8404a059b923cd475d9d35144f6c3153711303 Mon Sep 17 00:00:00 2001 From: Michiel Cottaar <MichielCottaar@protonmail.com> Date: Fri, 24 May 2024 16:06:16 +0100 Subject: [PATCH] Update code to use @defvar --- src/MRIBuilder.jl | 36 +++++++++++++------------- src/parts/epi_readouts.jl | 20 +++++++------- src/parts/helper_functions.jl | 2 +- src/parts/slice_select_rephases.jl | 4 +-- src/parts/spoilt_slice_selects.jl | 29 ++++++++++++--------- src/parts/trapezoids.jl | 33 ++++++++++++----------- src/plot.jl | 24 ++++++++--------- src/printing.jl | 13 +++------- src/sequence_io/pulseq.jl | 6 ++--- src/sequences/diffusion_spin_echoes.jl | 11 +++++--- src/sequences/gradient_echoes.jl | 4 +-- src/sequences/spin_echoes.jl | 9 ++++--- 12 files changed, 100 insertions(+), 91 deletions(-) diff --git a/src/MRIBuilder.jl b/src/MRIBuilder.jl index ae8cbbb..2837b2d 100644 --- a/src/MRIBuilder.jl +++ b/src/MRIBuilder.jl @@ -9,12 +9,12 @@ include("variables.jl") include("components/components.jl") include("containers/containers.jl") include("pathways.jl") -#include("parts/parts.jl") -#include("post_hoc.jl") -#include("sequences/sequences.jl") -#include("printing.jl") -#include("sequence_io/sequence_io.jl") -#include("plot.jl") +include("parts/parts.jl") +include("post_hoc.jl") +include("sequences/sequences.jl") +include("printing.jl") +include("sequence_io/sequence_io.jl") +include("plot.jl") import .BuildSequences: build_sequence, global_model, global_scanner, fixed export build_sequence, global_model, global_scanner, fixed @@ -34,22 +34,22 @@ export ContainerBlock, start_time, end_time, waveform, waveform_sequence, events import .Pathways: Pathway, duration_transverse, duration_dephase, bval, bmat, get_pathway export Pathway, duration_transverse, duration_dephase, bval, bmat, get_pathway -#import .Parts: dwi_gradients, readout_event, excitation_pulse, refocus_pulse, Trapezoid, SliceSelect, LineReadout, opposite_kspace_lines, SpoiltSliceSelect, SliceSelectRephase, EPIReadout, interpret_image_size -#export dwi_gradients, readout_event, excitation_pulse, refocus_pulse, Trapezoid, SliceSelect, LineReadout, opposite_kspace_lines, SpoiltSliceSelect, SliceSelectRephase, EPIReadout, interpret_image_size +import .Parts: dwi_gradients, readout_event, excitation_pulse, refocus_pulse, Trapezoid, SliceSelect, LineReadout, opposite_kspace_lines, SpoiltSliceSelect, SliceSelectRephase, EPIReadout, interpret_image_size +export dwi_gradients, readout_event, excitation_pulse, refocus_pulse, Trapezoid, SliceSelect, LineReadout, opposite_kspace_lines, SpoiltSliceSelect, SliceSelectRephase, EPIReadout, interpret_image_size -#import .PostHoc: adjust, merge_sequences -#export adjust, merge_sequences +import .PostHoc: adjust, merge_sequences +export adjust, merge_sequences -#import .Sequences: GradientEcho, SpinEcho, DiffusionSpinEcho, DW_SE, DWI -#export GradientEcho, SpinEcho, DiffusionSpinEcho, DW_SE, DWI +import .Sequences: GradientEcho, SpinEcho, DiffusionSpinEcho, DW_SE, DWI +export GradientEcho, SpinEcho, DiffusionSpinEcho, DW_SE, DWI -#import .SequenceIO: read_sequence, write_sequence -#export read_sequence, write_sequence +import .SequenceIO: read_sequence, write_sequence +export read_sequence, write_sequence -#import .Plot: plot_sequence -#export plot_sequence +import .Plot: plot_sequence +export plot_sequence -#import JuMP: @constraint, @objective, objective_function, value, Model -#export @constraint, @objective, objective_function, value, Model +import JuMP: @constraint, @objective, objective_function, value, Model +export @constraint, @objective, objective_function, value, Model end diff --git a/src/parts/epi_readouts.jl b/src/parts/epi_readouts.jl index dcd068e..92fb34c 100644 --- a/src/parts/epi_readouts.jl +++ b/src/parts/epi_readouts.jl @@ -2,7 +2,7 @@ module EPIReadouts import ...Containers: BaseSequence, get_index_single_TR import ..Trapezoids: Trapezoid, opposite_kspace_lines, LineReadout import ...Components: ADC -import ...Variables: get_free_variable, VariableType, qval, qval3, set_simple_constraints!, resolution, inverse_voxel_size, inverse_fov, resolution, get_readout, apply_simple_constraint!, effective_time, voxel_size, ramp_overlap, oversample, dwell_time +import ...Variables: get_free_variable, VariableType, set_simple_constraints!, get_readout, apply_simple_constraint!, variables, @defvar import ...Pathways: PathwayWalker, update_walker_till_time!, walk_pathway! """ @@ -49,10 +49,10 @@ function EPIReadout(; resolution::AbstractVector{<:Integer}, recenter=false, gro get_free_variable(nothing), ky_lines ) - apply_simple_constraint!(qval3(res.start_gradient), VariableType[-qval(pos)/2, ky_lines[1] * res.ky_step, 0.]) + apply_simple_constraint!(variables.qval3(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!(qval3(res.recenter_gradient), VariableType[sign * qval(pos)/2, -ky_lines[end] * res.ky_step, 0.]) + apply_simple_constraint!(variables.qval3(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) @@ -61,16 +61,18 @@ function EPIReadout(; resolution::AbstractVector{<:Integer}, recenter=false, gro return res end -inverse_fov(epi::EPIReadout) = [inverse_fov(epi.positive_line), 1e3 * epi.ky_step] -inverse_voxel_size(epi::EPIReadout) = [inverse_voxel_size(epi.positive_line), 1e3 * epi.ky_step * maximum(abs.(epi.ky_lines))] -resolution(epi::EPIReadout) = [resolution(epi.positive_line), maximum(abs.(epi.ky_lines))] +@defvar begin + inverse_fov(epi::EPIReadout) = [variables.inverse_fov(epi.positive_line), 1e3 * epi.ky_step] + inverse_voxel_size(epi::EPIReadout) = [variables.inverse_voxel_size(epi.positive_line), 1e3 * epi.ky_step * maximum(abs.(epi.ky_lines))] + resolution(epi::EPIReadout) = [variables.resolution(epi.positive_line), maximum(abs.(epi.ky_lines))] +end get_readout(epi::EPIReadout) = epi.positive_line -function effective_time(epi::EPIReadout) +@defvar function effective_time(epi::EPIReadout) index = findfirst(iszero, epi.ky_lines) if isnothing(index) error("EPI readout does not pass through the centre of k-space") end - return effective_time(epi, index * 2) + return variables.effective_time(epi, index * 2) end function get_index_single_TR(epi::EPIReadout, index::Integer) @@ -101,7 +103,7 @@ function walk_pathway!(epi::EPIReadout, walker::PathwayWalker, pulse_effects::Ve if nreadout[] > 0 return false end - update_walker_till_time!(walker, block_start_time + effective_time(epi)) + update_walker_till_time!(walker, block_start_time + variables.effective_time(epi)) return true end diff --git a/src/parts/helper_functions.jl b/src/parts/helper_functions.jl index 67dd765..927a226 100644 --- a/src/parts/helper_functions.jl +++ b/src/parts/helper_functions.jl @@ -8,7 +8,7 @@ import ..EPIReadouts: EPIReadout import ...BuildSequences: global_model, build_sequence, global_scanner import ...Containers: Sequence import ...Components: SincPulse, ConstantPulse, InstantPulse, SingleReadout, InstantGradient -import ...Variables: qvec, flat_time, rise_time, qval, apply_simple_constraint!, variables +import ...Variables: variables function _get_pulse(shape, flip_angle, phase, frequency, Nzeros, group, bandwidth, duration) diff --git a/src/parts/slice_select_rephases.jl b/src/parts/slice_select_rephases.jl index 397113e..5f291cb 100644 --- a/src/parts/slice_select_rephases.jl +++ b/src/parts/slice_select_rephases.jl @@ -1,7 +1,7 @@ module SliceSelectRephases import ...Containers: BaseSequence, get_index_single_TR import ..Trapezoids: SliceSelect, Trapezoid -import ...Variables: get_pulse, qval, apply_simple_constraint!, effective_time +import ...Variables: get_pulse, apply_simple_constraint!, variables, @defvar import ...Components: RFPulseComponent """ @@ -34,6 +34,6 @@ end get_index_single_TR(ss::SliceSelectRephase, ::Val{1}) = ss.slice_select get_index_single_TR(ss::SliceSelectRephase, ::Val{2}) = ss.rephase get_pulse(ssr::SliceSelectRephase) = ssr.slice_select -effective_time(ssr::SliceSelectRephase) = effective_time(ssr, 1) +@defvar effective_time(ssr::SliceSelectRephase) = variables.effective_time(ssr, 1) end \ No newline at end of file diff --git a/src/parts/spoilt_slice_selects.jl b/src/parts/spoilt_slice_selects.jl index 34aefd3..ebaa4e3 100644 --- a/src/parts/spoilt_slice_selects.jl +++ b/src/parts/spoilt_slice_selects.jl @@ -4,7 +4,7 @@ import LinearAlgebra: norm import StaticArrays: SVector import JuMP: @constraint, @objective, objective_function import ...BuildSequences: global_model, global_scanner -import ...Variables: VariableType, duration, rise_time, flat_time, effective_time, qval, gradient_strength, slew_rate, inverse_slice_thickness, get_free_variable, get_pulse, set_simple_constraints!, gradient_orientation +import ...Variables: VariableType, get_pulse, set_simple_constraints!, variables, @defvar import ...Components: ChangingGradient, ConstantGradient, RFPulseComponent import ...Containers: BaseBuildingBlock @@ -92,9 +92,11 @@ function SpoiltSliceSelect(pulse::RFPulseComponent; orientation=[0, 0, 1], group return res end -gradient_orientation(spoilt::SpoiltSliceSelect) = spoilt.orientation -duration_trap1(spoilt::SpoiltSliceSelect) = 2 * spoilt.rise_time1 + spoilt.flat_time1 - spoilt.diff_time -duration_trap2(spoilt::SpoiltSliceSelect) = 2 * spoilt.fall_time2 + spoilt.flat_time2 - spoilt.diff_time +@defvar begin + gradient_orientation(spoilt::SpoiltSliceSelect) = spoilt.orientation + duration_trap1(spoilt::SpoiltSliceSelect) = 2 * spoilt.rise_time1 + spoilt.flat_time1 - spoilt.diff_time + duration_trap2(spoilt::SpoiltSliceSelect) = 2 * spoilt.fall_time2 + spoilt.flat_time2 - spoilt.diff_time +end Base.keys(::SpoiltSliceSelect) = Val.((:rise1, :flat1, :fall1, :flat_pulse, :pulse, :rise2, :flat2, :fall2)) Base.getindex(spoilt::SpoiltSliceSelect, ::Val{:rise1}) = ChangingGradient(0., slew_rate(spoilt), gradient_orientation(spoilt), rise_time(spoilt)[1], spoilt.group) @@ -106,16 +108,19 @@ Base.getindex(spoilt::SpoiltSliceSelect, ::Val{:rise2}) = ChangingGradient(slew_ Base.getindex(spoilt::SpoiltSliceSelect, ::Val{:flat2}) = ConstantGradient(slew_rate(spoilt) * fall_time(spoilt)[2], gradient_orientation(spoilt), flat_time(spoilt)[2], spoilt.group) Base.getindex(spoilt::SpoiltSliceSelect, ::Val{:fall2}) = ChangingGradient(slew_rate(spoilt) * fall_time(spoilt)[2], -slew_rate(spoilt), gradient_orientation(spoilt), fall_time(spoilt)[2], spoilt.group) -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 -gradient_strength(spoilt::SpoiltSliceSelect) = slew_rate(spoilt) * max(spoilt.rise_time1, spoilt.fall_time2) +@defvar begin + 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 + gradient_strength(spoilt::SpoiltSliceSelect) = slew_rate(spoilt) * max(spoilt.rise_time1, spoilt.fall_time2) +end + get_pulse(spoilt::SpoiltSliceSelect) = spoilt.pulse -function all_gradient_strengths(spoilt::SpoiltSliceSelect) +@defvar function all_gradient_strengths(spoilt::SpoiltSliceSelect) grad1 = spoilt.slew_rate * rise_time(spoilt)[1] grad2 = grad1 - spoilt.slew_rate * flat_time(spoilt)[1] grad3 = spoilt.slew_rate * fall_time(spoilt)[2] diff --git a/src/parts/trapezoids.jl b/src/parts/trapezoids.jl index 7a6024c..0059b18 100644 --- a/src/parts/trapezoids.jl +++ b/src/parts/trapezoids.jl @@ -6,8 +6,7 @@ module Trapezoids import JuMP: @constraint import StaticArrays: SVector import LinearAlgebra: norm -import ...Variables: qval, rise_time, flat_time, slew_rate, gradient_strength, variables, duration, δ, get_free_variable, VariableType, inverse_bandwidth, effective_time, duration, set_simple_constraints!, scanner_constraints!, inverse_slice_thickness -import ...Variables: Variables, all_variables_symbols, dwell_time, inverse_fov, inverse_voxel_size, fov, voxel_size, get_gradient, get_pulse, get_readout, gradient_orientation, ramp_overlap, adjustable, adjust_internal +import ...Variables: variables, @defvar, scanner_constraints!, get_free_variable, set_simple_constraints!, gradient_orientation, VariableType import ...BuildSequences: global_model import ...Components: ChangingGradient, ConstantGradient, RFPulseComponent, ADC import ...Containers: BaseBuildingBlock @@ -107,14 +106,16 @@ gradient_orientation(pg::Trapezoid{1}) = pg.orientation get_group(pg::Trapezoid) = pg.group get_group(pg::BaseTrapezoid) = get_group(get_gradient(pg)) -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 -δ(g::Trapezoid) = rise_time(g) + flat_time(g) -duration(g::BaseTrapezoid) = 2 * rise_time(g) + flat_time(g) +@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) -qval(g::BaseTrapezoid, ::Nothing, ::Nothing) = δ(g) .* gradient_strength(g) .* 2π + qval(g::BaseTrapezoid, ::Nothing, ::Nothing) = δ(g) .* gradient_strength(g) .* 2π +end adjustable(::BaseTrapezoid) = :gradient @@ -176,11 +177,11 @@ end Base.keys(::SliceSelect) = (Val(:rise), Val(:flat), Val(:pulse), Val(:fall)) Base.getindex(pg::SliceSelect, ::Val{:pulse}) = (0., pg.pulse) -inverse_slice_thickness(ss::SliceSelect) = 1e3 * gradient_strength(ss.trapezoid) .* inverse_bandwidth(ss.pulse) +@defvar inverse_slice_thickness(ss::SliceSelect) = 1e3 * variables.gradient_strength(ss.trapezoid) .* variables.inverse_bandwidth(ss.pulse) get_pulse(ss::SliceSelect) = ss.pulse get_gradient(ss::SliceSelect) = ss.trapezoid -effective_time(ss::SliceSelect) = effective_time(ss, :pulse) +@defvar effective_time(ss::SliceSelect) = variables.effective_time(ss, :pulse) """ LineReadout(adc; ramp_overlap=1., orientation=nothing, group=nothing, variables...) @@ -221,10 +222,12 @@ end Base.keys(::LineReadout) = (Val(:rise), Val(:adc), Val(:flat), Val(:fall)) Base.getindex(lr::LineReadout, ::Val{:adc}) = ((1 - ramp_overlap(lr)) * rise_time(lr), lr.adc) -ramp_overlap(lr::LineReadout) = lr.ramp_overlap -inverse_fov(lr::LineReadout) = 1e3 * dwell_time(lr.adc) * gradient_strength(lr.trapezoid) * lr.adc.oversample -inverse_voxel_size(lr::LineReadout) = 1e3 * duration(lr.adc) * gradient_strength(lr.trapezoid) -effective_time(lr::LineReadout) = effective_time(lr, :adc) +@defvar begin + ramp_overlap(lr::LineReadout) = lr.ramp_overlap + inverse_fov(lr::LineReadout) = 1e3 * dwell_time(lr.adc) * gradient_strength(lr.trapezoid) * lr.adc.oversample + inverse_voxel_size(lr::LineReadout) = 1e3 * duration(lr.adc) * gradient_strength(lr.trapezoid) + effective_time(lr::LineReadout) = variables.effective_time(lr, :adc) +end get_readout(lr::LineReadout) = lr.adc get_gradient(lr::LineReadout) = lr.trapezoid diff --git a/src/plot.jl b/src/plot.jl index 7dd311c..b9215fb 100644 --- a/src/plot.jl +++ b/src/plot.jl @@ -1,7 +1,7 @@ module Plot import MakieCore: generic_plot_attributes! import ..Containers: BaseBuildingBlock, BaseSequence, waveform, events, start_time, ndim_grad, waveform_sequence -import ..Variables: duration, flip_angle, phase, make_generic, gradient_orientation +import ..Variables: make_generic, gradient_orientation, variables import ..Components: RFPulseComponent, ADC, InstantPulse, NoGradient, InstantGradient1D, InstantGradient3D """ @@ -16,7 +16,7 @@ struct SinglePlotLine event_amplitudes :: Vector{Float64} end -duration(pl::SinglePlotLine) = iszero(length(pl.times)) ? 0. : pl.times[end] +duration_line(pl::SinglePlotLine) = iszero(length(pl.times)) ? 0. : pl.times[end] SinglePlotLine(times::Vector{Float64}, amplitudes::Vector{Float64}) = SinglePlotLine(times, amplitudes, Float64[], Float64[]) function SinglePlotLine(control_points::AbstractVector{<:Tuple}, duration::Number) @@ -45,7 +45,7 @@ function SinglePlotLine(plot_lines::SinglePlotLine...) append!(amplitudes, pl.amplitudes) append!(event_times, pl.event_times .+ current_time) append!(event_amplitudes, pl.event_amplitudes) - current_time += duration(pl) + current_time += duration_line(pl) end return SinglePlotLine(times, amplitudes, event_times, event_amplitudes) end @@ -119,7 +119,7 @@ function SequenceDiagram(bbb::BaseBuildingBlock) if !all([wvs isa NoGradient for (_, wvs) in waveform_sequence(bbb)]) orientation = ndim_grad(bbb) == 3 ? 1. : gradient_orientation(bbb) for (index, symbol) in enumerate((:Gx, :Gy, :Gz)) - kwargs[symbol] = SinglePlotLine([(time, (orientation .* amplitude)[index]) for (time, amplitude) in waveform(bbb)], duration(bbb)) + kwargs[symbol] = SinglePlotLine([(time, (orientation .* amplitude)[index]) for (time, amplitude) in waveform(bbb)], variables.duration(bbb)) end end @@ -132,7 +132,7 @@ function SequenceDiagram(bbb::BaseBuildingBlock) end for (symbol, fn) in [(:RFx, cosd), (:RFy, sind)] if event isa InstantPulse - kwargs[symbol] = SinglePlotLine([0., duration(bbb)], [0., 0.], [delay], [flip_angle(event) * fn(phase(event))]) + kwargs[symbol] = SinglePlotLine([0., variables.duration(bbb)], [0., 0.], [delay], [variables.flip_angle(event) * fn(variables.phase(event))]) else points = Tuple{Float64, Float64}[] t_prev = p_prev = a_prev = nothing @@ -154,34 +154,34 @@ function SequenceDiagram(bbb::BaseBuildingBlock) p_prev = p a_prev = a end - kwargs[symbol] = SinglePlotLine(points, duration(bbb)) + kwargs[symbol] = SinglePlotLine(points, variables.duration(bbb)) end end elseif event isa ADC if :ADC in keys(kwargs) error("Cannot plot a building block with more than 1 ADC event.") end - if iszero(duration(event)) + if iszero(variables.duration(event)) kwargs[:ADC] = SinglePlotLine( - [0., duration(bbb)], + [0., variables.duration(bbb)], [0., 0.], [delay], [1.] ) else kwargs[:ADC] = SinglePlotLine( - [0., delay, delay, delay + duration(event), delay + duration(event), duration(bbb)], + [0., delay, delay, delay + variables.duration(event), delay + variables.duration(event), variables.duration(bbb)], [0., 0., 1., 1., 0., 0.], ) end elseif event isa InstantGradient1D - kwargs[:G] = SinglePlotLine([0., duration(bbb)], [0., 0.], [delay], [event.qval]) + kwargs[:G] = SinglePlotLine([0., variables.duration(bbb)], [0., 0.], [delay], [event.qval]) elseif event isa InstantGradient3D for (index, symbol) in enumerate([:Gx, :Gy, :Gz]) - kwargs[symbol] = SinglePlotLine([0., duration(bbb)], [0., 0.], [delay], [event.qval[index]]) + kwargs[symbol] = SinglePlotLine([0., variables.duration(bbb)], [0., 0.], [delay], [event.qval[index]]) end end end - return SequenceDiagram(duration(bbb); kwargs...) + return SequenceDiagram(variables.duration(bbb); kwargs...) end function SequenceDiagram(seq::BaseSequence) diff --git a/src/printing.jl b/src/printing.jl index 6162460..f72cfa0 100644 --- a/src/printing.jl +++ b/src/printing.jl @@ -1,8 +1,7 @@ module Printing import JuMP: value import Printf: @sprintf -import ..Variables: VariableType, variables, AbstractBlock, VariableNotAvailable, alternative_variables - +import ..Variables: VariableType, variables, AbstractBlock function _robust_value(possible_number::VariableType) try @@ -47,20 +46,14 @@ function Base.show(io::IO, block::AbstractBlock) end for fn in values(variables) - if fn in [fn_alt for (fn_alt, _, _, _) in values(alternative_variables)] - continue - end try numeric_value = _robust_value(fn(block)) if isnothing(numeric_value) continue end print(io, "$(nameof(fn))=$(numeric_value), ") - catch e - if e isa VariableNotAvailable - continue - end - rethrow() + catch + continue end end print(io, ")") diff --git a/src/sequence_io/pulseq.jl b/src/sequence_io/pulseq.jl index 6ca2a6a..035ca99 100644 --- a/src/sequence_io/pulseq.jl +++ b/src/sequence_io/pulseq.jl @@ -7,7 +7,7 @@ import ..PulseqIO.Types: PulseqSequence, PulseqBlock, PulseqTrapezoid, PulseqGra import ...Containers: Sequence, BuildingBlock, BaseBuildingBlock, events, waveform, iter_blocks import ...Components: GenericPulse, ADC, RFPulseComponent import ...Scanners: Scanner -import ...Variables: duration, nsamples, dwell_time, make_generic +import ...Variables: variables, make_generic function Sequence(pulseq::PulseqSequence; scanner=nothing, B0=nothing) if isnothing(scanner) @@ -145,8 +145,8 @@ function PulseqBlock(block::BaseBuildingBlock; BlockDurationRaster, AdcRasterTim error("Pulseq does not support a single building block containing multiple ADC events.") end adc = PulseqADC( - nsamples(event), - div(dwell_time(event), AdcRasterTime, RoundNearest), + variables.nsamples(event), + div(variables.dwell_time(event), AdcRasterTime, RoundNearest), Int(div(delay, 1e-3, RoundNearest)), 0., 0. ) diff --git a/src/sequences/diffusion_spin_echoes.jl b/src/sequences/diffusion_spin_echoes.jl index 4f8025a..bf847c9 100644 --- a/src/sequences/diffusion_spin_echoes.jl +++ b/src/sequences/diffusion_spin_echoes.jl @@ -2,7 +2,7 @@ module DiffusionSpinEchoes import ...Containers: Sequence import ...Parts: excitation_pulse, readout_event, interpret_image_size, Trapezoid, gradient_spoiler, refocus_pulse, dwi_gradients import ...Containers: start_time -import ...Variables: get_pulse, get_readout, echo_time, duration_transverse, delay, effective_time, diffusion_time, Δ, TR, TE, repetition_time, get_gradient +import ...Variables: get_pulse, get_readout, get_gradient, variables, @defvar import ...Pathways: Pathway, get_pathway import ...BuildSequences: build_sequence import ...Scanners: Default_Scanner @@ -64,8 +64,11 @@ get_pulse(ge::DiffusionSpinEcho) = (excitation=ge[:excitation], refocus=ge[:refo get_gradient(ge::DiffusionSpinEcho) = (gradient=ge[:gradient], gradient2=ge[:gradient2]) get_readout(ge::DiffusionSpinEcho) = ge.readout get_pathway(ge::DiffusionSpinEcho) = Pathway(ge, [90, 180], 1, group=:diffusion) -echo_time(ge::DiffusionSpinEcho) = 2 * (effective_time(ge, :refocus) - effective_time(ge, :excitation)) -delay(ge::DiffusionSpinEcho) = duration_transverse(ge) - echo_time(ge) -diffusion_time(ge::DiffusionSpinEcho) = start_time(ge, :gradient2) - start_time(ge, :gradient) + +@defvar begin + echo_time(ge::DiffusionSpinEcho) = 2 * (effective_time(ge, :refocus) - variables.effective_time(ge, :excitation)) + delay(ge::DiffusionSpinEcho) = variables.duration_transverse(ge) - variables.echo_time(ge) + diffusion_time(ge::DiffusionSpinEcho) = start_time(ge, :gradient2) - start_time(ge, :gradient) +end end \ No newline at end of file diff --git a/src/sequences/gradient_echoes.jl b/src/sequences/gradient_echoes.jl index 703b2cd..77b1241 100644 --- a/src/sequences/gradient_echoes.jl +++ b/src/sequences/gradient_echoes.jl @@ -1,7 +1,7 @@ module GradientEchoes import ...Containers: Sequence import ...Parts: excitation_pulse, readout_event, interpret_image_size, Trapezoid, gradient_spoiler -import ...Variables: get_pulse, get_readout, echo_time, duration_transverse, TR, TE, repetition_time +import ...Variables: get_pulse, get_readout, variables, @defvar import ...Pathways: Pathway, get_pathway import ...BuildSequences: build_sequence import ...Scanners: Default_Scanner @@ -47,7 +47,7 @@ end get_pulse(ge::GradientEcho) = ge.excitation get_readout(ge::GradientEcho) = ge.readout get_pathway(ge::GradientEcho) = Pathway(ge, [90], 1) -echo_time(ge::GradientEcho) = duration_transverse(ge) +@defvar echo_time(ge::GradientEcho) = variables.duration_transverse(ge) diff --git a/src/sequences/spin_echoes.jl b/src/sequences/spin_echoes.jl index 313ab23..90ec0a4 100644 --- a/src/sequences/spin_echoes.jl +++ b/src/sequences/spin_echoes.jl @@ -1,7 +1,7 @@ module SpinEchoes import ...Containers: Sequence import ...Parts: excitation_pulse, readout_event, interpret_image_size, Trapezoid, gradient_spoiler, refocus_pulse -import ...Variables: get_pulse, get_readout, echo_time, duration_transverse, delay, effective_time, TR, TR, repetition_time +import ...Variables: get_pulse, get_readout, variables, @defvar import ...Pathways: Pathway, get_pathway import ...BuildSequences: build_sequence import ...Scanners: Default_Scanner @@ -51,8 +51,11 @@ end get_pulse(ge::SpinEcho) = (excitation=ge.excitation, refocus=ge.refocus) get_readout(ge::SpinEcho) = ge.readout get_pathway(ge::SpinEcho) = Pathway(ge, [90, 180], 1) -echo_time(ge::SpinEcho) = 2 * (effective_time(ge, :refocus) - effective_time(ge, :excitation)) -delay(ge::SpinEcho) = duration_transverse(ge) - echo_time(ge) + +@defvar begin + echo_time(ge::SpinEcho) = 2 * (variables.effective_time(ge, :refocus) - variables.effective_time(ge, :excitation)) + delay(ge::SpinEcho) = variables.duration_transverse(ge) - variables.echo_time(ge) +end end \ No newline at end of file -- GitLab