diff --git a/src/MRIBuilder.jl b/src/MRIBuilder.jl index 59326aad5aff5ca73b78840c1f0d8f5309fb97ca..2905d9855b525dbaafc77c4bab84d23c3d91a641 100644 --- a/src/MRIBuilder.jl +++ b/src/MRIBuilder.jl @@ -26,8 +26,8 @@ export variables, duration, effective_time, flip_angle, amplitude, phase, freque import .Components: InstantPulse, ConstantPulse, SincPulse, GenericPulse, InstantGradient, SingleReadout, ADC export InstantPulse, ConstantPulse, SincPulse, GenericPulse, InstantGradient, SingleReadout, ADC -import .Containers: ContainerBlock, start_time, end_time, waveform, waveform_sequence, events, BaseBuildingBlock, BuildingBlock, Wait, BaseSequence, nrepeat, Sequence, AlternativeBlocks, match_blocks!, get_index_single_TR -export ContainerBlock, start_time, end_time, waveform, waveform_sequence, events, BaseBuildingBlock, BuildingBlock, Wait, BaseSequence, nrepeat, Sequence, AlternativeBlocks, match_blocks!, get_index_single_TR +import .Containers: ContainerBlock, start_time, end_time, waveform, waveform_sequence, events, BaseBuildingBlock, BuildingBlock, Wait, BaseSequence, nrepeat, Sequence, AlternativeBlocks, match_blocks!, get_index_single_TR, readout_times, edge_times +export ContainerBlock, start_time, end_time, waveform, waveform_sequence, events, BaseBuildingBlock, BuildingBlock, Wait, BaseSequence, nrepeat, Sequence, AlternativeBlocks, match_blocks!, get_index_single_TR, readout_times, edge_times import .Pathways: Pathway, duration_transverse, duration_dephase, bval, bmat, get_pathway export Pathway, duration_transverse, duration_dephase, bval, bmat, get_pathway diff --git a/src/components/readouts/ADCs.jl b/src/components/readouts/ADCs.jl index b4a6b7e932acc218f376da851b99b9f7f205dad3..ca5792f655eaeb5de27f20079435b2bade6ca257 100644 --- a/src/components/readouts/ADCs.jl +++ b/src/components/readouts/ADCs.jl @@ -48,6 +48,7 @@ function ADC(; resolution=nothing, dwell_time=nothing, time_to_center=nothing, c return res end +readout_times(adc::ADC) = range(0, duration(adc), Int(nsamples(adc))) oversample(adc::ADC) = adc.oversample nsamples(adc::ADC) = resolution(adc) * oversample(adc) dwell_time(adc::ADC) = adc.dwell_time diff --git a/src/components/readouts/readouts.jl b/src/components/readouts/readouts.jl index b28a9cdf2b30b2e2f103e855395df3fee74d74f0..0b6ec5de05defcccd182ee81baf25c3ba1504542 100644 --- a/src/components/readouts/readouts.jl +++ b/src/components/readouts/readouts.jl @@ -3,6 +3,6 @@ include("ADCs.jl") include("single_readouts.jl") import ..AbstractTypes: ReadoutComponent -import .ADCs: ADC +import .ADCs: ADC, readout_times import .SingleReadouts: SingleReadout end \ No newline at end of file diff --git a/src/components/readouts/single_readouts.jl b/src/components/readouts/single_readouts.jl index c814763d3fa89bed7f2ee7f6242cfffd0058135c..dfaf8fca2890f152d2e92d48243e3e3480335c4f 100644 --- a/src/components/readouts/single_readouts.jl +++ b/src/components/readouts/single_readouts.jl @@ -2,7 +2,7 @@ module SingleReadouts import JuMP: @constraint import ...AbstractTypes: ReadoutComponent import ....Variables: duration, effective_time, make_generic -import ..ADCs: ADC +import ..ADCs: ADC, readout_times """ SingleReadout() @@ -28,6 +28,7 @@ end duration(::SingleReadout) = 0. effective_time(::SingleReadout) = 0. +readout_times(::SingleReadout) = [0.] make_generic(::SingleReadout) = ADC(1, 0., 0., 0.) end \ No newline at end of file diff --git a/src/containers/abstract.jl b/src/containers/abstract.jl index 669ff1b088842410b35d211e5806ac3e70695386..8cb582a5d4efecab4f5d915f00ca0b76d67aedc2 100644 --- a/src/containers/abstract.jl +++ b/src/containers/abstract.jl @@ -1,5 +1,6 @@ module Abstract import ...Variables: AbstractBlock, duration, effective_time +import ...Components.Readouts: readout_times """ Parent type for `BuildingBlock` or `BaseSequence`, i.e., any building block that contains other MRI components/blocks. @@ -43,5 +44,25 @@ Also see [`duration`](@ref), [`start_time`](@ref), and [`end_time`](@ref) effective_time(container::ContainerBlock, index, indices...) = start_time(container, index) + effective_time(container[index], indices...) +""" + readout_times(sequence/ADC) + +Return the times of all of the readout events in ms. +""" +function readout_times end + +""" + edge_times(container) + +Returns all the edge times during a sequence in ms. + +Edges are defined as any time, when: +- the edge of a building block +- the slope of the gradient profile changes suddenly +- an RF pulse starts or ends +""" +function edge_times end + + end \ No newline at end of file diff --git a/src/containers/base_sequences.jl b/src/containers/base_sequences.jl index 0302288c3158e4f565cc972abaf1750e779e175a..281580dbccc547c50d94d18a98cdb23e62f6a4f8 100644 --- a/src/containers/base_sequences.jl +++ b/src/containers/base_sequences.jl @@ -7,7 +7,7 @@ import JuMP: @constraint import ...Variables: get_free_variable, repetition_time, VariableType, duration, variables, VariableNotAvailable, Variables, set_simple_constraints!, TR, make_generic import ...BuildSequences: global_model import ...Components: EventComponent -import ..Abstract: ContainerBlock, start_time +import ..Abstract: ContainerBlock, start_time, readout_times, edge_times import ..BuildingBlocks: Wait, BuildingBlock, BaseBuildingBlock """ @@ -83,6 +83,22 @@ repetition_time(bs::BaseSequence) = duration(bs) duration(bs::BaseSequence{0}) = 0. duration(bs::BaseSequence) = sum(duration.(bs); init=0.) +function readout_times(seq::BaseSequence) + res = Float64[] + for (index, block) in enumerate(seq) + append!(res, readout_times(block) .+ start_time(seq, index)) + end + return res +end + +function edge_times(seq::BaseSequence) + res = Float64[] + for (index, block) in enumerate(seq) + append!(res, edge_times(block) .+ start_time(seq, index)) + end + return unique(res) +end + """ Sequence(blocks; name=:Sequence, variables...) Sequence(blocks...; name=:Sequence, variables...) @@ -153,4 +169,6 @@ function make_generic(seq::BaseSequence) return Sequence(blocks) end + + end diff --git a/src/containers/building_blocks.jl b/src/containers/building_blocks.jl index 2856f2f21f1aa9b6347facc442c7fc9f8d73eb66..7fe8d03bd0d667a0cb8bea97b2ce55dddc2f52df 100644 --- a/src/containers/building_blocks.jl +++ b/src/containers/building_blocks.jl @@ -5,9 +5,9 @@ module BuildingBlocks import LinearAlgebra: norm import JuMP: @constraint import StaticArrays: SVector -import ..Abstract: ContainerBlock, start_time +import ..Abstract: ContainerBlock, start_time, readout_times, edge_times, end_time import ...BuildSequences: global_model -import ...Components: BaseComponent, GradientWaveform, EventComponent, NoGradient, ChangingGradient, ConstantGradient, split_gradient, DelayedEvent, RFPulseComponent, ReadoutComponent +import ...Components: BaseComponent, GradientWaveform, EventComponent, NoGradient, ChangingGradient, ConstantGradient, split_gradient, DelayedEvent, RFPulseComponent, ReadoutComponent, InstantGradient import ...Variables: qval, bmat_gradient, effective_time, get_free_variable, qval3, slew_rate, gradient_strength import ...Variables: VariableType, duration, make_generic, get_pulse, get_readout, scanner_constraints! @@ -112,14 +112,12 @@ equal_key(i1, i2) = i1 == i2 function start_time(building_block::BaseBuildingBlock, index) time = 0. - prev_time = 0. for key in keys(building_block) if equal_key(key, index) - return prev_time + return time end component = building_block[key] if component isa GradientWaveform - prev_time = time time += duration(component) end end @@ -206,6 +204,29 @@ function bmat_gradient(bb::BaseBuildingBlock, qstart, index1, index2) end bmat_gradient(bb::BaseBuildingBlock, qstart) = bmat_gradient(bb, qstart, nothing, nothing) +function readout_times(bb::BaseBuildingBlock) + res = Float64[] + for (key, event) in events(bb) + if event isa ReadoutComponent + append!(res, readout_times(event) .+ start_time(bb, key)) + end + end + return res +end + +function edge_times(bb::BaseBuildingBlock) + res = Float64[] + for key in keys(bb) + object = bb[key] + if object isa Union{GradientWaveform, RFPulseComponent, InstantGradient} + @show key start_time(bb, key) end_time(bb, key) + push!(res, start_time(bb, key)) + push!(res, end_time(bb, key)) + end + end + return sort(unique(res)) +end + """ BuildingBlock(waveform, events; duration=nothing, orientation=nothing, group) diff --git a/src/containers/containers.jl b/src/containers/containers.jl index f2df3a1bf9527e1a54a9fa79f6a488b89f4819cb..4bd983bffaafc2e8b1e36d815efe846d19ff5693 100644 --- a/src/containers/containers.jl +++ b/src/containers/containers.jl @@ -4,7 +4,7 @@ include("building_blocks.jl") include("base_sequences.jl") include("alternatives.jl") -import .Abstract: ContainerBlock, start_time, end_time, effective_time +import .Abstract: ContainerBlock, start_time, end_time, effective_time, readout_times, edge_times import .BuildingBlocks: BaseBuildingBlock, BuildingBlock, Wait, waveform, waveform_sequence, events, ndim_grad import .BaseSequences: BaseSequence, Sequence, nrepeat, get_index_single_TR import .Alternatives: AlternativeBlocks, match_blocks!