Direct Reconstruction
To implement our direct reconstruction algorithms we need to define a few more methods and types. We will start by defining the parameters for the backprojection and for the filtered backprojection. Afterwards we can implement the algorithm itself.
Parameters and Processing
For convenience we first introduce a new abstract type for the direct reconstruction parameters:
abstract type AbstractDirectRadonReconstructionParameters <: AbstractRadonReconstructionParameters endThe backprojection parameters are simple and only contain the number of angles:
@parameter struct RadonBackprojectionParameters <: AbstractDirectRadonReconstructionParameters
angles::Vector{Float64}
endThe filtered backprojection parameters are more complex and contain the number of angles and optionally the filter which should be used:
@parameter struct RadonFilteredBackprojectionParameters <: AbstractDirectRadonReconstructionParameters
angles::Vector{Float64}
filter::Union{Nothing, Vector{Float64}} = nothing
endSince we have defined no default values for the angles, they are required to be set by the user. A more advanced implementation would also allow for the geometry to be set.
Next we will implement the process steps for both of our backprojection variants. Since RadonKA.jl expects 2D or 3D arrays we have to transform our time series accordingly.
function (params::AbstractDirectRadonReconstructionParameters)(algoT::Type{<:AbstractDirectRadonAlgorithm}, data::AbstractArray{T, 4}) where {T}
result = []
for i = 1:size(data, 4)
push!(result, params(algoT, view(data, :, :, :, i)))
end
return cat(result..., dims = 4)
end
(params::RadonBackprojectionParameters)(::Type{<:AbstractDirectRadonAlgorithm}, data::AbstractArray{T, 3}) where {T} = RadonKA.backproject(data, params.angles)
(params::RadonFilteredBackprojectionParameters)(::Type{<:AbstractDirectRadonAlgorithm}, data::AbstractArray{T, 3}) where {T} = RadonKA.backproject_filtered(data, params.angles; filter = params.filter)Algorithm
The direct reconstruction algorithm has essentially no state to store between reconstructions and thus only needs its parameters as fields. We want our algorithm to accept any combination of our preprocessing and direct reconstruction parameters. This we encode in a new type:
@chain struct DirectRadonParameters{P <: AbstractRadonPreprocessingParameters, R <: AbstractDirectRadonReconstructionParameters} <: AbstractRadonParameters
pre::P
reco::R
endThis composite type simply chains the result of our preprocessing step into our reco step. See the API for @chain for more information.
Now we can define the algorithm type itself using the @reconstruction macro. The macro automatically generates:
- A mutable struct with the parameter field and internal infrastructure
- A constructor accepting the parameter
- Interface methods:
Base.put!,Base.take!,Base.wait,Base.isready,Base.lock,Base.unlock - A parameter accessor method
It's also possible to implement these functions manually, see the corresponding docstrings for information
@reconstruction struct DirectRadonAlgorithm{D <: DirectRadonParameters} <: AbstractDirectRadonAlgorithm
@parameter parameter::D
endThe way the behaviour is implemented here, the algorithm does not buffer any inputs and instead blocks until the current reconstruction is done. Outputs are stored until they are retrieved.
This page was generated using Literate.jl.