Skip to content
Snippets Groups Projects
Verified Commit 14097ed2 authored by Michiel Cottaar's avatar Michiel Cottaar
Browse files

Define variables at sequence level

parent a3dbcb21
No related branches found
No related tags found
No related merge requests found
...@@ -18,8 +18,8 @@ export build_sequence, global_model, global_scanner ...@@ -18,8 +18,8 @@ export build_sequence, global_model, global_scanner
import .Scanners: Scanner, B0, Siemens_Connectom, Siemens_Prisma, Siemens_Terra import .Scanners: Scanner, B0, Siemens_Connectom, Siemens_Prisma, Siemens_Terra
export Scanner, B0, Siemens_Connectom, Siemens_Prisma, Siemens_Terra export Scanner, B0, Siemens_Connectom, Siemens_Prisma, Siemens_Terra
import .Variables: variables, duration, effective_time, flip_angle, amplitude, phase, frequency, bandwidth, N_left, N_right, qval, δ, rise_time, flat_time, slew_rate, gradient_strength, qvec, qval_square, slice_thickness, inverse_slice_thickness, fov, inverse_fov, voxel_size, inverse_voxel_size, resolution, nsamples, oversample, dwell_time, ramp_overlap, spoiler_scale import .Variables: variables, duration, effective_time, flip_angle, amplitude, phase, frequency, bandwidth, N_left, N_right, qval, δ, rise_time, flat_time, slew_rate, gradient_strength, qvec, qval_square, slice_thickness, inverse_slice_thickness, fov, inverse_fov, voxel_size, inverse_voxel_size, resolution, nsamples, oversample, dwell_time, ramp_overlap, spoiler_scale, TR
export variables, duration, effective_time, flip_angle, amplitude, phase, frequency, bandwidth, N_left, N_right, qval, δ, rise_time, flat_time, slew_rate, gradient_strength, qvec, qval_square, slice_thickness, inversne_slice_thickness, fov, inverse_fov, voxel_size, inverse_voxel_size, resolution, nsamples, oversample, dwell_time, ramp_overlap, spoiler_scale export variables, duration, effective_time, flip_angle, amplitude, phase, frequency, bandwidth, N_left, N_right, qval, δ, rise_time, flat_time, slew_rate, gradient_strength, qvec, qval_square, slice_thickness, inversne_slice_thickness, fov, inverse_fov, voxel_size, inverse_voxel_size, resolution, nsamples, oversample, dwell_time, ramp_overlap, spoiler_scale, TR
import .Components: InstantPulse, ConstantPulse, SincPulse, GenericPulse, InstantGradient, SingleReadout, ADC import .Components: InstantPulse, ConstantPulse, SincPulse, GenericPulse, InstantGradient, SingleReadout, ADC
export InstantPulse, ConstantPulse, SincPulse, GenericPulse, InstantGradient, SingleReadout, ADC export InstantPulse, ConstantPulse, SincPulse, GenericPulse, InstantGradient, SingleReadout, ADC
......
...@@ -4,7 +4,7 @@ Defines [`BaseSequence`](@ref) and [`Sequence`](@ref) ...@@ -4,7 +4,7 @@ Defines [`BaseSequence`](@ref) and [`Sequence`](@ref)
module Sequences module Sequences
import StaticArrays: SVector import StaticArrays: SVector
import JuMP: @constraint import JuMP: @constraint
import ...Variables: get_free_variable, TR, VariableType, duration import ...Variables: get_free_variable, TR, VariableType, duration, variables, VariableNotAvailable, Variables
import ...BuildSequences: global_model import ...BuildSequences: global_model
import ...Components: EventComponent import ...Components: EventComponent
import ..Abstract: ContainerBlock, start_time import ..Abstract: ContainerBlock, start_time
...@@ -94,29 +94,59 @@ Defines an MRI sequence from a vector of building blocks. ...@@ -94,29 +94,59 @@ Defines an MRI sequence from a vector of building blocks.
- [`nrepeat`](@ref): how often the sequence will repeat itself (keep at default of 0 to repeat indefinetely). - [`nrepeat`](@ref): how often the sequence will repeat itself (keep at default of 0 to repeat indefinetely).
- [`TR`](@ref): how long between repeats in ms (defaults to the duration of the sequence). Can be set to `nothing` to be a free variable. - [`TR`](@ref): how long between repeats in ms (defaults to the duration of the sequence). Can be set to `nothing` to be a free variable.
""" """
struct Sequence{N} <: BaseSequence{N} struct Sequence{N, S} <: BaseSequence{N}
blocks :: SVector{N, Pair{<:Union{Symbol, Nothing}, <:ContainerBlock}} blocks :: SVector{N, Pair{<:Union{Symbol, Nothing}, <:ContainerBlock}}
TR :: VariableType TR :: VariableType
end end
function Sequence(blocks::AbstractVector; TR=:min) function Sequence(blocks::AbstractVector; TR=:min, name=:Sequence)
blocks = to_block_pair.(blocks) blocks = to_block_pair.(blocks)
actual_duration = sum(pair -> duration(pair[2]), blocks; init=0.) actual_duration = sum(pair -> duration(pair[2]), blocks; init=0.)
if TR == :min if TR == :min
TR = actual_duration TR = actual_duration
end end
res = Sequence{length(blocks)}(SVector{length(blocks)}(blocks), get_free_variable(TR)) res = Sequence{length(blocks), name}(SVector{length(blocks)}(blocks), get_free_variable(TR))
if !(res.TR isa Number) || !(duration(res) isa Number) if !(res.TR isa Number) || !(duration(res) isa Number)
@constraint global_model() res.TR >= actual_duration @constraint global_model() res.TR >= actual_duration
end end
return res return res
end end
for fn in keys(variables)
if fn in (:duration, :TR)
continue
end
@eval function Variables.$fn(seq::Sequence)
res = []
for (name, block) in seq.blocks
if isnothing(name)
continue
end
try
push!(res, name => Variables.$fn(block))
catch e
if e isa VariableNotAvailable
continue
end
rethrow()
end
end
if length(res) > 0
return NamedTuple(res)
else
error("None of the building blocks of $(typeof(seq)) define $($fn)")
end
end
end
Base.show(io::IO, ::Type{<:Sequence{N, S}}) where {N, S} = print(io, S)
Sequence(blocks...; kwargs...) = Sequence([blocks...]; kwargs...) Sequence(blocks...; kwargs...) = Sequence([blocks...]; kwargs...)
get_index_single_TR(s::Sequence, i::Integer) = s.blocks[i][2] get_index_single_TR(s::Sequence, i::Integer) = s.blocks[i][2]
Base.getindex(seq::Sequence, sym::Symbol) = seq[findfirst(p -> p[1] == sym, seq.blocks)] Base.getindex(seq::Sequence, sym::Symbol) = seq[findfirst(p -> p[1] == sym, seq.blocks)]
nrepeat(::Sequence) = 0 nrepeat(::Sequence) = 0
TR(s::Sequence) = s.TR
to_block_pair(pair::Pair) = pair[1] => to_block(pair[2]) to_block_pair(pair::Pair) = pair[1] => to_block(pair[2])
to_block_pair(other) = nothing => to_block(other) to_block_pair(other) = nothing => to_block(other)
......
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