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

Prettify Sequence printing

parent 69aeeda2
No related branches found
No related tags found
No related merge requests found
...@@ -30,7 +30,9 @@ abstract type GradientBlock <: BuildingBlock end ...@@ -30,7 +30,9 @@ abstract type GradientBlock <: BuildingBlock end
Parent type for all types combining one or more pulses/gradients. Parent type for all types combining one or more pulses/gradients.
Required methods: Required methods:
- [`get_children_blocks`](@ref): return all the [`BuildingBlock`](@ref) objects includes in this container with their indices. - [`get_children_blocks`](@ref)(container): return all the [`BuildingBlock`](@ref) objects includes in this container with their indices.
- [`start_time`](@ref)(container, index): returns the starting time of the child corresponding to `index` relative to the start of the `container` in ms.
- `Base.getindex`(container, index): get child [`BuildingBlock`](@ref) corresponding to `index`.
""" """
abstract type ContainerBlock <: BuildingBlock end abstract type ContainerBlock <: BuildingBlock end
...@@ -50,6 +52,7 @@ Returns the starting time of the specific [`BuildingBlock`](@ref) within the con ...@@ -50,6 +52,7 @@ Returns the starting time of the specific [`BuildingBlock`](@ref) within the con
The [`BuildingBlock`](@ref) is defined by one or more indices as defined below. The [`BuildingBlock`](@ref) is defined by one or more indices as defined below.
""" """
start_time(bb) = 0. start_time(bb) = 0.
start_time(container, index1, index2, more_indices...) = start_time(container, index1) + start_time(container[index1], index2, more_indices)
""" """
end_time(container, args...) end_time(container, args...)
...@@ -58,6 +61,7 @@ Returns the end time of the specific [`BuildingBlock`](@ref) within the containe ...@@ -58,6 +61,7 @@ Returns the end time of the specific [`BuildingBlock`](@ref) within the containe
The [`BuildingBlock`](@ref) is defined by one or more indices as defined below. The [`BuildingBlock`](@ref) is defined by one or more indices as defined below.
""" """
end_time(bb) = duration(bb) end_time(bb) = duration(bb)
end_time(container, index1, index2, more_indices...) = start_time(container, index1) + end_time(container[index1], index2, more_indices)
""" """
...@@ -109,36 +113,78 @@ Returns a list of function that can be called to constrain the `building_block`. ...@@ -109,36 +113,78 @@ Returns a list of function that can be called to constrain the `building_block`.
variables(bb::BuildingBlock) = variables(typeof(bb)) variables(bb::BuildingBlock) = variables(typeof(bb))
function Base.show(io::IO, block::BuildingBlock) struct BuildingBlockPrinter{T<:BuildingBlock}
print(io, string(typeof(block)), "(") bb::T
internal_print(io, block) index::Any
print(io, ")") start_time::Union{Nothing, Number}
spaces::Int
end end
function internal_print(io::IO, block::BuildingBlock)
Base.show(io::IO, block::BuildingBlock) = print(io, BuildingBlockPrinter(block, nothing, nothing, 0))
function _robust_value(possible_number)
try
return value(possible_number)
catch
return nothing
end
end
function Base.show(io::IO, printer::BuildingBlockPrinter)
block = printer.bb
if !isnothing(printer.index)
print(io, printer.index, ": ")
end
print(io, string(typeof(block)), "(")
variable_names = nameof.(variables(block))
printed_duration = false
if !isnothing(printer.start_time)
print(io, "t=", @sprintf("%.3g", printer.start_time))
dur = _robust_value(duration(block))
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) for name in propertynames(block)
value = getproperty(block, name) value = getproperty(block, name)
if value isa AbstractJuMPScalar || value isa Model || string(name)[1] == '_' if name in variable_names || value isa Model || value isa BuildingBlock || string(name)[1] == '_'
continue continue
end end
print(io, name, "=", repr(value), ", ") print(io, name, "=", repr(value), ", ")
end end
if has_values(block) for fn in variables(block)
for fn in variables(block) if printed_duration && fn == duration
if fn == duration continue
continue end
end numeric_value = _robust_value(fn(block))
numeric_value = value(fn(block)) if isnothing(numeric_value)
printed_value = @sprintf("%.3g", numeric_value) continue
print(io, "$(nameof(fn))=$(printed_value), ") end
printed_value = @sprintf("%.3g", numeric_value)
print(io, "$(nameof(fn))=$(printed_value), ")
end
print(io, ")")
if block isa ContainerBlock
use_start_time = isnothing(printer.start_time) ? 0. : printer.start_time
print(io, ":")
for (child_index, child_block) in get_children_blocks(block)
child_printer = BuildingBlockPrinter(
child_block, child_index,
_robust_value(start_time(block, child_index) + use_start_time),
printer.spaces + 2
)
print(io, "\n", repeat(' ', printer.spaces), child_printer)
end end
end end
end end
# The `start_time` and `end_time` functions are properly defined in "sequence_builders.jl"
function start_time end
function end_time end
""" """
set_simple_constraints!(model, block, kwargs) set_simple_constraints!(model, block, kwargs)
......
...@@ -5,7 +5,7 @@ module Sequences ...@@ -5,7 +5,7 @@ module Sequences
import JuMP: Model, @constraint import JuMP: Model, @constraint
import ...BuildSequences: @global_model_constructor import ...BuildSequences: @global_model_constructor
import ...Variables: variables, start_time, duration, VariableType, get_free_variable, TR import ...Variables: variables, start_time, duration, VariableType, get_free_variable, TR
import ...BuildingBlocks: BuildingBlock, ContainerBlock, to_block, get_children_blocks, scanner_constraints!, fixed import ...BuildingBlocks: BuildingBlock, ContainerBlock, to_block, get_children_blocks, scanner_constraints!, fixed, BuildingBlockPrinter
import ..FixedBlocks: FixedBlock import ..FixedBlocks: FixedBlock
abstract type AbstractSequence <: ContainerBlock end abstract type AbstractSequence <: ContainerBlock end
...@@ -26,7 +26,7 @@ or be embedded as a [`BuildingBlock`](@ref) into higher-order `Sequence` or othe ...@@ -26,7 +26,7 @@ or be embedded as a [`BuildingBlock`](@ref) into higher-order `Sequence` or othe
""" """
struct Sequence <: AbstractSequence struct Sequence <: AbstractSequence
model :: Model model :: Model
blocks :: Vector{<:BuildingBlock} _blocks :: Vector{<:BuildingBlock}
TR :: VariableType TR :: VariableType
function Sequence(model::Model, blocks::AbstractVector; TR=nothing, scanner=nothing) function Sequence(model::Model, blocks::AbstractVector; TR=nothing, scanner=nothing)
seq = new( seq = new(
...@@ -46,9 +46,9 @@ end ...@@ -46,9 +46,9 @@ end
Sequence(model::Model, blocks...; TR=nothing, scanner=nothing) = Sequence(model, [blocks...]; TR=TR, scanner=scanner) Sequence(model::Model, blocks...; TR=nothing, scanner=nothing) = Sequence(model, [blocks...]; TR=TR, scanner=scanner)
Base.length(seq::AbstractSequence) = length(seq.blocks) Base.length(seq::AbstractSequence) = length(seq._blocks)
Base.getindex(seq::AbstractSequence, index) = seq.blocks[index] Base.getindex(seq::AbstractSequence, index) = seq._blocks[index]
get_children_blocks(seq::AbstractSequence) = enumerate(seq.blocks) get_children_blocks(seq::AbstractSequence) = enumerate(seq._blocks)
""" """
start_time(sequence::Sequence, index::Integer, args...) start_time(sequence::Sequence, index::Integer, args...)
...@@ -57,34 +57,24 @@ Returns the starting time of the [`BuildingBlock`](@ref) with index `index`. ...@@ -57,34 +57,24 @@ Returns the starting time of the [`BuildingBlock`](@ref) with index `index`.
Additional `args` can be used to select a sub-block of that [`BuildingBlock`](@ref). Additional `args` can be used to select a sub-block of that [`BuildingBlock`](@ref).
The starting time is returned with respect to the start of this sequence. The starting time is returned with respect to the start of this sequence.
""" """
start_time(seq::AbstractSequence) = 0. start_time(seq::AbstractSequence, index::Integer) = isone(index) ? start_time(seq) : (start_time(seq, index-1) + duration(seq[index-1]))
start_time(seq::AbstractSequence, index::Integer) = iszero(index) ? start_time(seq) : (start_time(seq, index-1) + duration(seq[index]))
start_time(seq::AbstractSequence, index::Integer, args...) = start_time(seq, index) + start_time(seq[index], args...)
"""
end_time(sequence::Sequence, index::Integer, args...)
Returns the end time of the [`BuildingBlock`](@ref) with index `index`.
Additional `args` can be used to select a sub-block of that [`BuildingBlock`](@ref).
The end time is returned with respect to the start of this sequence.
"""
end_time(seq::AbstractSequence, index::Integer) = start_time(seq, index) + duration(seq[index])
end_time(seq::AbstractSequence, index::Integer, args...) = start_time(seq, index) + end_time(seq[index], args...)
duration(seq::AbstractSequence) = end_time(seq, length(seq)) duration(seq::AbstractSequence) = end_time(seq, length(seq))
TR(seq::AbstractSequence) = seq.TR TR(seq::AbstractSequence) = seq.TR
variables(::Type{<:Sequence}) = [TR] variables(::Type{<:Sequence}) = [TR]
# print timings when printing sequences
Base.show(io::IO, seq::AbstractSequence) = print(io, BuildingBlockPrinter(seq, nothing, 0., 0))
struct FixedSequence <: AbstractSequence struct FixedSequence <: AbstractSequence
blocks :: Vector{<:BuildingBlock} _blocks :: Vector{<:BuildingBlock}
TR :: Number TR :: Number
end end
function fixed(seq::Sequence) function fixed(seq::Sequence)
FixedSequence( FixedSequence(
fixed.(seq.blocks), fixed.(seq._blocks),
value(TR(seq)) value(TR(seq))
) )
end end
......
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