API for Solvers
This page contains documentation of the public API of the AbstractImageReconstruction. In the Julia REPL one can access this documentation by entering the help mode with ?
Algorithm and Parameters
AbstractImageReconstruction.AbstractImageReconstructionAlgorithm — Type
AbstractImageReconstructionAlgorithmAbstract type for image reconstruction algorithms. Must implement put! and take! functions. Serialization expects a constructor with a single AbstractImageReconstructionParameters argument.
AbstractImageReconstruction.AbstractImageReconstructionParameters — Type
AbstractImageReconstructionParametersAbstract type for image reconstruction parameters. An algorithm consists of one or more process steps, each can have its own parameters. Parameters can be arbitrarily nested. Parameters are callable and can be invoked directly on algorithm instances:
result = param(algo, inputs...)or a type-based implementation:
result = param(typeof(algo), inputs...)Interface
Implement one of:
(param::MyParameters)(::Type{<:MyAlgorithm}, inputs...)for type-based processing(param::MyParameters)(algo::MyAlgorithm, inputs...)for instance-based processing (defaults to type-based)
AbstractImageReconstruction.@reconstruction — Macro
@reconstruction [constructor={true, false}] [hash={true, false}] struct AlgoName{P <: Params} <: AbstractBase
@parameter parameter::P
field::Type = default
field = default
@init hook!(algo)
endDefine a reconstruction algorithm struct with all boilerplate automatically generated.
The @reconstruction macro generates:
- A mutable struct with algorithm infrastructure fields (channel for FIFO buffering)
- A simple constructor that accepts only the parameter (if
constructor=true) - Implementation of all interface methods:
put!,take!,isready,wait,lock,unlock - A
hashmethod (ifhash=true)
Configuration Options
constructor=true(default) - Auto-generate a simple constructorconstructor=false- No constructor generated (write custom constructor)hash=true(default) - Generate ahashmethodhash=false- Do not generate ahashmethod
Syntax
Required
@parameter parameter::ParameterType- The main parameter field (immutable)
Optional State Fields
field::Type = default- Typed field with default valuefield = default- Untyped field with default value
Optional Hooks
@init hook!(algo)- Custom initialization hook after construction
Examples
# Simple algorithm with default constructor
@reconstruction mutable struct MyAlgorithm <: AbstractImageReconstructionAlgorithm
@parameter params::MyParameters
state::Vector{Float64} = Float64[]
counter::Int = 0
end
# Algorithm with custom initialization
@reconstruction mutable struct AlgorithmWithInit <: CustomBase
@parameter params::MyParameters
cache::Dict{String, Any} = Dict()
@init function setup!(algo::AlgorithmWithInit)
algo.cache["initialized"] = true
end
end
# Algorithm without auto-generated constructor
@reconstruction constructor=false mutable struct CustomConstructorAlgorithm
@parameter params::MyParameters
state::Vector{Float64}
end
function CustomConstructorAlgorithm(params)
# Custom initialization logic
state = ...
algo = CustomConstructorAlgorithm(params, state, @reconstruction_internals CustomConstructorAlgorithm)
# ... more setup ...
return algo
endAbstractImageReconstruction.@parameter — Macro
@parameter [constructor={true,false}] [hash={true,false}] (mutable) struct Name{...} <: AbstractImageReconstructionParameters
field1::Type1 [= default1]
field2::Type2 [= default2]
...
@validate begin
@assert field1 >= ... "message"
...
end
endDefine a parameter struct for image reconstruction algorithms.
The @parameter macro generates:
- A struct with the specified fields
- A keyword constructor for easy instantiation:
Name(field1=val1, field2=val2)with (optional) validation - A
validate!function for parameter validation (if@validateis used)
Configuration Options
constructor=true(default) - Auto-generate a keyword constructorconstructor=false- No keyword constructor generated (write custom constructor)- Note: When using
constructor=falsewith fields that have default values (e.g.,field::Int = 10), those defaults are NOT available via keyword arguments. Handle defaults in your custom constructor. - Note: When using
constructor=falsewith@validate, you must manually callvalidate!in your custom constructor. hash=true(default) - Generate ahashmethod for the parameter typehash=false- Do not generate ahashmethod
Syntax
Required
field::Type- Required field with type annotationfield::Type = default- Optional field with default value
Optional Validation
@validate- Block of validation assertions
Examples
# Simple parameter with validation
@parameter struct MyParameters <: AbstractImageReconstructionParameters
iterations::Int = 10
tolerance::Float64 = 1e-6
@validate begin
@assert iterations > 0 "iterations must be positive"
@assert tolerance > 0 "tolerance must be positive"
end
end
# Parameter without auto-generated constructor
@parameter constructor=false struct CustomParams
field::Int
@validate begin
@assert field > 0 "field must be positive"
end
end
function CustomParams(;field::Int)
params = CustomParams(field)
validate!(params) # Must call manually when constructor=false
return params
endAbstractImageReconstruction.@chain — Macro
@chain [constructor={true,false}] [hash={true,false}] struct Name{...} <: AbstractImageReconstructionParameters
step1::P1 [= default1]
step2::P2 [= default2]
...
@validate @assert condition "message"
endDefine a composite parameter type that chains multiple processing steps.
The @chain macro generates:
- A struct with the specified field parameters
- A keyword constructor for easy instantiation
- A
validate!function (if@validateis used) - Call methods that chain the step parameters sequentially
When called, the composite parameter executes each step in order:
result = params.step1(algo, inputs...)
result = params.step2(algo, result...)
...
return resultConfiguration Options
constructor=true(default) - Auto-generate a keyword constructorconstructor=false- No keyword constructor generated (write custom constructor)- Note: When using
constructor=falsewith fields that have default values (e.g.,step::Params = Params()), those defaults are NOT available via keyword arguments. Handle defaults in your custom constructor. - Note: When using
constructor=falsewith@validate, you must manually callvalidate!in your custom constructor. hash=true(default) - Generate ahashmethod for the parameter typehash=false- Do not generate ahashmethod
Syntax
Required
step1::P1- First processing step parameter typestep2::P2- Second processing step parameter type- Each field should be a parameter type that implements
(param, algo, inputs...)
Optional
@validate- Block of validation assertions
Examples
# Chain preprocessing and reconstruction steps
@chain struct CompositeParameters <: AbstractImageReconstructionParameters
pre::RadonPreprocessingParameters
reco::RadonBackprojectionParameters
end
# Chain without auto-generated constructor
@chain constructor=false struct CustomChain <: AbstractImageReconstructionParameters
step1::StepParams
@validate begin
@assert step1.value >= 0 "step value must be non-negative"
end
end
function CustomChain(;step1::StepParams)
chain = CustomChain(step1)
validate!(chain) # Must call manually when constructor=false
return chain
endAbstractImageReconstruction.reconstruct — Function
reconstruct(algo::T, u) where {T<:AbstractImageReconstructionAlgorithm}Reconstruct an image from input u using algorithm algo. The àlgo will be locked until the result is available or an error occurs.
AbstractImageReconstruction.validate! — Function
validate!(param::AbstractImageReconstructionParameters)Validate a parameter object independent of any specific algorithm.
This is the default, algorithm-agnostic validation method. Concrete parameter types can specialize this method to enforce internal invariants, e.g.:
function validate!(p::MyParams)
@assert p.iterations > 0 "iterations must be positive"
@assert length(p.reg) > 0 "regularization vector must not be empty"
return p
endBy default, this method is a no-op and simply returns param
validate!(algo, param::AbstractImageReconstructionParameters)Validate a parameter object in the context of a specific reconstruction algorithm algo.
The above macros and functions are all that is required to implement when using the provided macros. For custom structs without the macros, it's also necessary to implement the following functions:
Base.take! — Method
take!(algo::AbstractImageReconstructionAlgorithm)Remove and return a stored result from the algorithm algo. Blocks until a result is available.
Base.unlock — Method
unlock(algo::AbstractImageReconstructionAlgorithm)Release a lock on the algorithm algo.
Base.isready — Method
isready(algo::AbstractImageReconstructionAlgorithm)Determine if the algorithm algo has a result available.
AbstractImageReconstruction.parameter — Function
parameter(algo::AbstractImageReconstructionAlgorithm)Return the parameters of the algorithm algo.
parameter(param::AbstractUtilityReconstructionParameters)Return the wrapped parameter. Can themselves be utility parameters again
RecoPlan
AbstractImageReconstruction.toPlan — Function
toPlan(param::Union{AbstractImageReconstructionParameters, AbstractImageReconstructionAlgorithm})Convert an AbstractImageReconstructionParameters or AbstractImageReconstructionAlgorithm to a (nested) RecoPlan.
AbstractImageReconstruction.build — Function
build(plan::RecoPlan{T}) where {T}Recursively build a plan from a RecoPlan by converting all properties to their actual values using keyword argument constructors.
Base.propertynames — Method
propertynames(plan::RecoPlan{T}) where {T}Return a tupel of configurable properties of T. Unlike propertynames(T) this does not include properties starting with _.
Base.getproperty — Method
getproperty(plan::RecoPlan{T}, name::Symbol) where {T}Get the property name of plan. Equivalent to plan.name.
Base.getindex — Method
getindex(plan::RecoPlan{T}, name::Symbol) where {T}Return the Observable for the name property of plan. Equivalent to plan[name].
Base.setproperty! — Method
setproperty!(plan::RecoPlan{T}, name::Symbol, x::X) where {T, X}Set the property name of plan to x. Equivalent to plan.name = x. Triggers callbacks attached to the property.
AbstractImageReconstruction.setAll! — Function
setAll!(plan::RecoPlan{T}, name::Symbol, x) where {T<:AbstractImageReconstructionParameters}Recursively set the property name of each nested RecoPlan of plan to x.
setAll!(plan::AbstractRecoPlan; kwargs...)Call setAll! with each given keyword argument.
setAll!(plan::AbstractRecoPlan, dict::Union{Dict{Symbol, Any}, Dict{String, Any}})Call setAll! with each entries of the dict.
AbstractImageReconstruction.clear! — Function
clear!(plan::RecoPlan{T}, preserve::Bool = true) where {T<:AbstractImageReconstructionParameters}Clear all properties of plan. If preserve is true, nested RecoPlans are preserved.
Base.ismissing — Method
ismissing(plan::RecoPlan, name::Symbol)Indicate if the property name of plan is missing.
Observables.on — Method
on(f, plan::RecoPlan, property::Symbol; kwargs...)Adds function f as listener to property of plan. The function is called whenever the property is changed with setproperty!.
Observables.off — Method
off(plan::RecoPlan, property::Symbol, f)Remove f from the listeners of property of plan.
AbstractImageReconstruction.RecoPlanStyle — Type
RecoPlanStyleStyle for serializing RecoPlan and related types using StructUtils.
This style customizes the serialization and deserialization of reconstruction plans, parameters, and algorithms. It uses StructUtils.lower for serialization and StructUtils.lift for deserialization, with special handling for metadata preservation.
Serialization (lower)
The StructUtils.lower method for RecoPlanStyle:
- For
RecoPlans: stores_module,_typetags and serializes nested plans - For parameters/algorithms: applies default
StructUtils.lowerfromFIELD_STYLE - Custom types can be handled by defining
StructUtils.lower(::RecoPlanStyle, ::Type{T}) - Array elements are recursively lowered
Deserialization (lift/make)
Deserialization has two layers:
lift: Converts TOML values back to Julia types- Used for simple types:
Symbol,Enum,AbstractArray,Type,Complex - Union types handled by
deserializeUnionwhich tries each member - Users can define custom
StructUtils.lift(::RecoPlanStyle, ::Type{T}, source)
- Used for simple types:
make/make!: ReconstructsRecoPlaninstances- Only needed when the plan structure itself must be customized
makecreates the plan,make!fills in properties
Customization
Users can customize serialization by:
Defining
StructUtils.lowerfor specific types:StructUtils.lower(::RecoPlanStyle, x::MyType) = Dict("special" => x.value)Defining
StructUtils.liftfor specific types:StructUtils.lift(::RecoPlanStyle, ::Type{MyType}, dict) = MyType(dict["special"]), dictDefining custom plan styles extending
CustomPlanStyle:struct MyStyle <: CustomPlanStyle end StructUtils.lower(::MyStyle, x) = StructUtils.lower(RecoPlanStyle(), x)Styles based on
CustomPlanStyledefault toRecoPlanStyle.
Plan Levels
The serialization system supports two levels of style customization:
plan_style: Controls how plans are built and which style'smake/make!methods are usedfield_style: Controls how field values (parameters, algorithms) are serialized/deserialized
These are passed to savePlan and loadPlan:
savePlan(io, plan; plan_style=MyPlanStyle(), field_style=MyFieldStyle())
loaded = loadPlan(io, modules; plan_style=MyPlanStyle(), field_style=MyFieldStyle())Example
plan = toPlan(algo)
savePlan("myplan.toml", plan)
loaded = loadPlan("myplan.toml", [MyModule, OtherModule])AbstractImageReconstruction.CustomPlanStyle — Type
CustomPlanStyleAbstract type for custom plan serialization styles.
Subtypes of CustomPlanStyle can override StructUtils.lower, StructUtils.make! and StructUtils.lift to provide custom serialization and deserialization behavior for specific types.
Use CustomPlanStyle when you need different serialization for certain fields while keeping the standard plan structure. The default delegation to RecoPlanStyle is provided for convenience.
Example
struct CustomStyle <: CustomPlanStyle end
StructUtils.lower(::CustomStyle, x::SpecialType) = Dict("custom" => x.data)
loadPlan("plan.toml", modules; field_style=CustomStyle())AbstractImageReconstruction.savePlan — Function
savePlan(file::Union{AbstractString, IO}, plan::RecoPlan; plan_style=RecoPlanStyle(), field_style=RecoPlanStyle())Save the plan to the file in TOML format.
Keywords
plan_style: Style for plan-level serialization (controls howRecoPlaninstances are built)field_style: Style for field-level serialization (controls how parameter and algorithm fields are serialized)
See also loadPlan, RecoPlanStyle.
AbstractImageReconstruction.loadPlan — Function
loadPlan(filename::Union{AbstractString, IO}, modules::Vector{Module}; plan_style=RecoPlanStyle(), field_style=RecoPlanStyle())Load a RecoPlan from a TOML file. The modules argument is a vector of modules that contain the types used in the plan. After loading the plan, the listeners are attached to the properties using loadListener!.
Keywords
plan_style: Style for plan-level deserialization (controls howRecoPlaninstances are built)field_style: Style for field-level deserialization (controls how parameter and algorithm fields are deserialized)
Example
plan = loadPlan("myplan.toml", [MyModule, OtherModule])AbstractTrees.parent — Method
parent(plan::RecoPlan)Return the parent of plan.
AbstractImageReconstruction.parent! — Method
parent!(plan::RecoPlan, parent::RecoPlan)Set the parent of plan to parent.
AbstractImageReconstruction.parentproperty — Function
parentproperty(plan::RecoPlan)Return the property name of plan in its parent, s.t. getproperty(parent(plan), parentproperty(plan)) === plan. Return nothing if plan has no parent.
AbstractImageReconstruction.parentproperties — Function
parentproperties(plan::RecoPlan)Return a vector of property names of plan in its parent, s.t. getproperty(parent(plan), last(parentproperties(plan))) === plan. Return an empty vector if plan has no parent.
Miscellaneous
AbstractImageReconstruction.LinkedPropertyListener — Type
LinkedPropertyListener(fn, target::RecoPlan, targetProp, source::RecoPlan, sourceProp)Connect two properties of RecoPlans. Set target.targetProp to fn(source.sourceProp) whenever source.sourceProp changes and target.targetProp was not changed outside of the listener.
AbstractImageReconstruction.ProcessResultCache — Type
ProcessResultCache(params::AbstractImageReconstructionParameters; maxsize = 1, kwargs...)Cache of size maxsize for the results of parameter calls:
(params::P)(algo, inputs...)The cache key is based on the hash of the algorithm (or its type), the wrapped parameter, and the inputs.
The same ProcessResultCache instance can be shared between algorithms constructed from the same plan. The cache is transparent with respect to the properties of the underlying parameter. Cached entries can be invalidated by calling empty!(params). (Shallow) copies a RecoPlan{ProcessCache} share a cache instance.
AbstractImageReconstruction.toKwargs — Method
toKwargs(value::AbstractImageReconstructionParameters; kwargs...)Convert a AbstractImageReconstructionParameters to a Dict{Symbol, Any} of each property.
Optional keyword arguments:
- flatten::Vector{DataType}: Types to flatten, per default only
AbstractImageReconstructionParametersare flattened. - ignore::Vector{Symbol}: Properties to ignore.
- default::Dict{Symbol, Any}: Default values for properties that are missing.
- overwrite::Dict{Symbol, Any}: Overwrite values for properties.
AbstractImageReconstruction.fromKwargs — Function
fromKwargs(type::Type{T}; kwargs...) where {T}Create a new instance of type from the keyword arguments. Only properties that are part of type are considered.