diff --git a/src/parts/helper_functions.jl b/src/parts/helper_functions.jl index 038e3a39ed756353e62427894a175830ba2b8ddd..95906c11e553286810a63ab944a2eeb68fa6cc32 100644 --- a/src/parts/helper_functions.jl +++ b/src/parts/helper_functions.jl @@ -222,7 +222,7 @@ function dwi_gradients(; type=:trapezoid, optimise=false, scanner=nothing, refoc end for var_func in match if var_func isa Symbol - var_func = variables[var_func] + var_func = getproperty(variables, var_func) end apply_simple_constraint!(var_func(g1), var_func(g2)) end diff --git a/src/variables.jl b/src/variables.jl index bcd4067a2998c6638348f402c594f8042f8f867a..7df980611f87fe8818835f1fcffbea76f583d201 100644 --- a/src/variables.jl +++ b/src/variables.jl @@ -87,14 +87,10 @@ Check whether variable is defined for a specific sub-type. """ variable_defined_for(var::Variable, ::Val{T}) where {T <: AbstractBlock} = hasmethod(var.f, (T, )) -struct _Variables - variables :: Dict{Symbol, AnyVariable} -end - """ -Main interface to all the MRIBuilder sequence variables. +Main module containing all the MRIBuilder sequence variables. -All variables are available as members of this object, e.g. +All variables are available as members of this module, e.g. `variables.echo_time` returns the echo time variable. New variables can be defined using [`@defvar`](@ref). @@ -105,15 +101,8 @@ After sequence generation you can get the variable values by calling `variables.echo_time(seq)`. For the sequence defined above this would return 70. (or a number very close to that). """ -variables = _Variables(Dict{Symbol, AnyVariable}()) - -Base.getindex(v::_Variables, i::Symbol) = getfield(v, :variables)[i] -Base.keys(v::_Variables) = keys(getfield(v, :variables)) -Base.values(v::_Variables) = values(getfield(v, :variables)) - -Base.propertynames(v::_Variables) = Tuple(keys(getfield(v, :variables))) - -Base.getproperty(v::_Variables, s::Symbol) = v[s] +baremodule variables +end """ @@ -217,11 +206,14 @@ function _defvar(func_def, getter=nothing) expressions = Expr[] for func_name in func_names push!(expressions, quote - $(esc(func_name)) = if $(QuoteNode(func_name)) in keys(variables) - variables[$(QuoteNode(func_name))] - else + $(esc(func_name)) = try + variables.$(func_name) + catch e + if !(e isa UndefVarError) + rethrow() + end function $(func_name) end - getfield(variables, :variables)[$(QuoteNode(func_name))] = Variable($(QuoteNode(func_name)), $(func_name), $getter) + variables.$(func_name) = Variable($(QuoteNode(func_name)), $(func_name), $getter) end if $(esc(func_name)) isa AlternateVariable error("$($(esc(func_name)).name) is defined through $($(esc(func_name)).other_var). Please define that variable instead.") @@ -251,11 +243,11 @@ end Duration of the sequence or building block in ms. """ -duration +variables.duration function def_alternate_variable!(name::Symbol, other_var::Symbol, from_other::Function, to_other::Union{Nothing, Function}, inverse::Bool) - getfield(variables, :variables)[name] = AlternateVariable(name, other_var, from_other, to_other, inverse) + setproperty!(variables, name, AlternateVariable(name, other_var, from_other, to_other, inverse)) end def_alternate_variable!(:spoiler_scale, :qval, q->1e-3 * 2Ï€/q, l->1e-3 * 2Ï€/l, true) @@ -402,7 +394,7 @@ function (var::Variable)(event::Tuple{<:VariableType, <:AbstractBlock}, args...; end function (var::AlternateVariable)(args...; kwargs...) - other_var = variables[var.other_var] + other_var = getproperty(variables, var.other_var) apply_from_other(res::VariableType) = var.from_other(res) function apply_from_other(res::AbstractVector{<:VariableType}) try @@ -451,7 +443,7 @@ function set_simple_constraints!(block::AbstractBlock, kwargs) real_kwargs = Dict(key => value for (key, value) in kwargs if !isnothing(value)) for (key, value) in real_kwargs - var = variables[key] + var = getproperty(variables, key) if var isa AlternateVariable if var.other_var in keys(real_kwargs) error("Set constraints on both $key and $(var.other_var), however they are equivalent.") @@ -461,7 +453,7 @@ function set_simple_constraints!(block::AbstractBlock, kwargs) invert_value(::Val{:min}) = var.inverse ? Val(:max) : Val(:min) invert_value(::Val{:max}) = var.inverse ? Val(:min) : Val(:max) invert_value(value::AbstractVector) = invert_value.(value) - apply_simple_constraint!(variables[var.other_var](block), invert_value(value)) + apply_simple_constraint!(getproperty(variables, var.other_var)(block), invert_value(value)) else apply_simple_constraint!(var(block), value) end