From b82fb7a34fb38d2870add76388d4caa2254835a6 Mon Sep 17 00:00:00 2001 From: Michiel Cottaar <michiel.cottaar@ndcn.ox.ac.uk> Date: Wed, 21 Feb 2024 15:15:48 +0000 Subject: [PATCH] Add pathway variables the proper way to the variables list --- src/MRIBuilder.jl | 2 +- src/pathways.jl | 3 +- src/printing.jl | 109 +++------------------------------------------- src/variables.jl | 8 +++- 4 files changed, 14 insertions(+), 108 deletions(-) diff --git a/src/MRIBuilder.jl b/src/MRIBuilder.jl index 9eddcdb..f0086cb 100644 --- a/src/MRIBuilder.jl +++ b/src/MRIBuilder.jl @@ -10,7 +10,7 @@ include("components/components.jl") include("containers/containers.jl") include("pathways.jl") include("parts/parts.jl") -#include("printing.jl") +include("printing.jl") import .BuildSequences: build_sequence, global_model, global_scanner, fixed export build_sequence, global_model, global_scanner, fixed diff --git a/src/pathways.jl b/src/pathways.jl index 4ef0139..6fc3a77 100644 --- a/src/pathways.jl +++ b/src/pathways.jl @@ -3,7 +3,7 @@ import LinearAlgebra: norm, tr import StaticArrays: SVector, SMatrix import ..Components: NoGradient, RFPulseComponent, ReadoutComponent, InstantGradient, GradientWaveform, DelayedEvent import ..Containers: BaseSequence, Sequence, BaseBuildingBlock, waveform, events, waveform_sequence, start_time, AlternativeBlocks -import ..Variables: qvec, qval, bmat_gradient, VariableType, effective_time, duration, TR, variables +import ..Variables: qvec, qval, bmat_gradient, VariableType, effective_time, duration, TR, bmat, bval, area_under_curve, duration_dephase, duration_transverse """ @@ -180,7 +180,6 @@ for fn in (:qvec, :area_under_curve, :bmat, :bval, :duration_dephase, :duration_ end error("get_pathway returned unexpected type for $seq") end - @eval variables[$(QuoteNode(fn))] = $fn end diff --git a/src/printing.jl b/src/printing.jl index 5cdbe53..95eebcd 100644 --- a/src/printing.jl +++ b/src/printing.jl @@ -1,26 +1,7 @@ module Printing import JuMP: value import Printf: @sprintf -import ..BuildingBlocks: BuildingBlock, get_children_indices, VariableNotAvailable -import ..Alternatives: AlternativeBlocks -import ..Overlapping: AbstractOverlapping, waveform, interruptions -import ..Sequences: Sequence -import ..Variables: VariableType, duration, start_time, variables, alternative_variables, effective_time, flip_angle -import ..Pulses: GenericPulse - -struct BuildingBlockPrinter{T<:BuildingBlock} - bb::T - start_time::Union{Nothing, Number} - spaces::Int -end - -Base.show(io::IO, block::BuildingBlock) = print(io, BuildingBlockPrinter(block, nothing, 0)) -Base.show(io::IO, seq::Sequence) = print(io, BuildingBlockPrinter(seq, 0., 0)) - -function Base.show(io::IO, alt_printer::BuildingBlockPrinter{<:AlternativeBlocks}) - block = alt_printer.bb - print(io, "AlternativeBlocks(", block.name, ", ", length(block), " options)") -end +import ..Variables: VariableType, variables, AbstractBlock, VariableNotAvailable, alternative_variables function _robust_value(possible_number::VariableType) @@ -42,21 +23,8 @@ end _robust_value(possible_tuple::Tuple) = _robust_value([possible_tuple...]) -function Base.show(io::IO, printer::BuildingBlockPrinter) - block = printer.bb +function Base.show(io::IO, block::AbstractBlock) print(io, nameof(typeof(block)), "(") - printed_duration = false - if !isnothing(printer.start_time) - print(io, "t=", @sprintf("%.3g", printer.start_time)) - - dur = _robust_value(duration(block)) - @assert !(dur isa AbstractVector) - if !isnothing(dur) && !iszero(dur) - print(io, "-", @sprintf("%.3g", printer.start_time + dur)) - printed_duration = true - end - print(io, ", ") - end for name in propertynames(block) ft = fieldtype(typeof(block), name) if ( @@ -67,11 +35,9 @@ function Base.show(io::IO, printer::BuildingBlockPrinter) continue end if ( - block isa AbstractOverlapping && ( - ft <: Union{Nothing, BuildingBlock} || - (ft <: AbstractVector && eltype(ft) <: BuildingBlock) || - name == :interruptions - )) + ft <: Union{Nothing, AbstractBlock} || + (ft <: AbstractVector && eltype(ft) <: AbstractBlock) + ) continue end @@ -79,9 +45,6 @@ function Base.show(io::IO, printer::BuildingBlockPrinter) end for fn in values(variables) - if printed_duration && fn == duration - continue - end if fn in [fn_alt for (fn_alt, _, _, _) in values(alternative_variables)] continue end @@ -104,68 +67,6 @@ function Base.show(io::IO, printer::BuildingBlockPrinter) end end print(io, ")") - if block isa AbstractOverlapping - print(io, ":") - ref_start_time = isnothing(printer.start_time) ? 0. : printer.start_time - inter = copy(interruptions(block)) - prev_time = 0. - for (index_grad, (time, grad)) in enumerate(waveform(block)) - while length(inter) > 0 && index_grad == (inter[1].index + 1) - to_print = popfirst!(inter) - t_eff = ref_start_time + prev_time + to_print.time - as_printer = BuildingBlockPrinter(to_print.object, t_eff - effective_time(to_print.object), printer.spaces + 2) - print(io, "\n", repeat(' ', printer.spaces + 2), "- ", @sprintf("%.3g", t_eff), ": ", as_printer) - end - printed_grad = "[" * join(map(v -> @sprintf("%.3g", v), grad), ", ") * "]" - print(io, "\n", repeat(' ', printer.spaces + 2), "- ", @sprintf("%.3g", ref_start_time + time), ": ", printed_grad) - prev_time = time - end - end -end - -function Base.show(io::IO, printer::BuildingBlockPrinter{<:Sequence}) - seq = printer.bb - print(io, "Sequence(") - d = _robust_value(duration(seq)) - if !isnothing(d) - if !isnothing(printer.start_time) - print(io, "t=", @sprintf("%.3g", printer.start_time), "-", @sprintf("%.3g", printer.start_time + d), ", ") - else - print(io, "duration=", @sprintf("%.3g", d), ",") - end - end - TR = _robust_value(seq.TR) - if !isnothing(TR) && isfinite(TR) - print(io, "TR=", Int(round(TR))) - end - print(io, "):") - - for child_index in get_children_indices(seq) - child_block = seq[child_index] - child_printer = BuildingBlockPrinter( - child_block, - isnothing(printer.start_time) ? nothing : _robust_value(start_time(seq, child_index) + printer.start_time), - printer.spaces + 2 - ) - print(io, "\n", repeat(' ', printer.spaces + 2), "- ", child_index, ": ", child_printer) - end - end -function Base.show(io::IO, printer::BuildingBlockPrinter{<:GenericPulse}) - fp = printer.bb - pp(value::Number) = @sprintf("%.3g", value) - - print(io, "GenericPulse(") - if isnothing(printer.start_time) - print(io, "duration=", pp(duration(fp))) - else - print(io, "t=", pp(printer.start_time), "-", pp(printer.start_time + duration(fp))) - end - print(io, ", flip_angle=", pp(flip_angle(fp)), ", effective_time=", pp(effective_time(fp)), ")") -end - - - - end \ No newline at end of file diff --git a/src/variables.jl b/src/variables.jl index 8ff7409..9a15631 100644 --- a/src/variables.jl +++ b/src/variables.jl @@ -36,6 +36,12 @@ all_variables_symbols = [ :sequence => [ :TR => "Time on which an MRI sequence repeats itself in ms.", :Δ => "Diffusion time in ms (i.e., time between start of the diffusion-weighted gradients).", + :qvec => "Net dephasing due to gradients in rad/um.", + :area_under_curve => "Net dephasing due to gradients in rad/um (same as [`qvec`](@ref)).", + :bmat => "Full 3x3 diffusion-weighting matrix in ms/um^2.", + :bval => "Size of diffusion-weighting in ms/um^2 (trace of [`bmat`](@ref)).", + :duration_dephase => "Net T2' dephasing experienced over a sequence (in ms).", + :duration_transverse => "Net T2 signal loss experienced over a sequence (in ms). This is the total duration spins spent in the transverse plane.", ], :pulse => [ :flip_angle => "The flip angle of the RF pulse in degrees", @@ -70,7 +76,7 @@ all_variables_symbols = [ :resolution => "Number of voxels in the final readout. During the optimisation this might produce non-integer values, but this will be fixed after optimsation.", :oversample => "How much to oversample with ([`nsamples`](@ref) / [`resolution`](@ref))", :ramp_overlap => "Fraction of overlap between ADC event and underlying gradient pulse ramp (between 0 and 1)." - ] + ], ] """ -- GitLab