From e656851cc0259d1b4ef336a2296ab35ec1da0a9b Mon Sep 17 00:00:00 2001 From: nHackel Date: Thu, 1 Aug 2024 08:05:10 +0200 Subject: [PATCH 1/2] Refactor DirectSelectionFrequencyFilterParameters struct Refactor the DirectSelectionFrequencyFilterParameters struct to allow for both Integer and CartesianIndex{2} types in the type parameters --- src/PreProcessing/FrequencyFilterParameter.jl | 10 ++++---- test/Reconstruction.jl | 24 +++++++++++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/PreProcessing/FrequencyFilterParameter.jl b/src/PreProcessing/FrequencyFilterParameter.jl index 8daf810..be75e56 100644 --- a/src/PreProcessing/FrequencyFilterParameter.jl +++ b/src/PreProcessing/FrequencyFilterParameter.jl @@ -9,14 +9,16 @@ function process(::Type{<:AbstractMPIRecoAlgorithm}, params::NoFrequencyFilterPa end export DirectSelectionFrequencyFilterParameters -Base.@kwdef struct DirectSelectionFrequencyFilterParameters{T <: Integer, FIT <: AbstractVector{T}} <: AbstractFrequencyFilterParameter +Base.@kwdef struct DirectSelectionFrequencyFilterParameters{T <: Union{Integer, CartesianIndex{2}}, FIT <: AbstractVector{T}} <: AbstractFrequencyFilterParameter freqIndices::FIT end - -function process(::Type{<:AbstractMPIRecoAlgorithm}, params::DirectSelectionFrequencyFilterParameters, file::MPIFile) +function process(::Type{<:AbstractMPIRecoAlgorithm}, params::DirectSelectionFrequencyFilterParameters{T}, file::MPIFile) where T <: Integer nFreq = params.freqIndices nReceivers = rxNumChannels(file) - return collect(vec(CartesianIndices((nFreq, nReceivers)))) + return vec([CartesianIndex{2}(i, j) for i in nFreq, j in nReceivers]) +end +function process(::Type{<:AbstractMPIRecoAlgorithm}, params::DirectSelectionFrequencyFilterParameters{T}, file::MPIFile) where T <: CartesianIndex{2} + return params.freqIndices end # Could possible also be nested diff --git a/test/Reconstruction.jl b/test/Reconstruction.jl index 0ec7295..b535ed5 100644 --- a/test/Reconstruction.jl +++ b/test/Reconstruction.jl @@ -136,4 +136,28 @@ c10a = reconstruct("SinglePatch", b; params..., reg = [L2Regularization(0.0)], weightingParams = WhiteningWeightingParameters(whiteningMeas = bSF)) c10b = reconstruct("SinglePatch", b; params..., reg = [L2Regularization(0.0)], weightingParams = CompositeWeightingParameters([WhiteningWeightingParameters(whiteningMeas = bSF), RowNormWeightingParameters()])) @test isapprox(arraydata(c9a), arraydata(c9b)) + + # Frequency Filtering + params = Dict{Symbol, Any}() + params[:SNRThresh] = 5 + params[:frames] = 1:1 + params[:minFreq] = 80e3 + params[:recChannels] = 1:2 + params[:iterations] = 1 + params[:spectralLeakageCorrection] = true + params[:sf] = bSF + params[:reg] = [L2Regularization(0.0f0)] + params[:solver] = Kaczmarz + + freqs = filterFrequencies(bSF; minFreq = params[:minFreq], recChannels = params[:recChannels], SNRThresh = params[:SNRThresh]) + c11a = reconstruct("SinglePatch", b; params...) + c11b = reconstruct("SinglePatch", b; params..., freqFilter = DirectSelectionFrequencyFilterParameters(freqIndices = freqs)) + @test isapprox(arraydata(c11a), arraydata(c11b)) + + freq_components = map(f -> f[1], freqs) + custom_freqs = vec([CartesianIndex{2}(i, j) for i in freq_components, j in rxNumChannels(bSF)]) + c11c = reconstruct("SinglePatch", b; params..., freqFilter = DirectSelectionFrequencyFilterParameters(freqIndices = custom_freqs)) + c11d = reconstruct("SinglePatch", b; params..., freqFilter = DirectSelectionFrequencyFilterParameters(freqIndices = freq_components)) + @test isapprox(arraydata(c11c), arraydata(c11d)) + end From 25d1c010a26b54beb24e38fe54314f7497009f74 Mon Sep 17 00:00:00 2001 From: nHackel Date: Thu, 1 Aug 2024 08:47:03 +0200 Subject: [PATCH 2/2] Add CompositeFreqeuncyFilterParameters --- src/PreProcessing/FrequencyFilterParameter.jl | 12 +++++++++++- test/Reconstruction.jl | 17 +++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/PreProcessing/FrequencyFilterParameter.jl b/src/PreProcessing/FrequencyFilterParameter.jl index be75e56..3bbac0a 100644 --- a/src/PreProcessing/FrequencyFilterParameter.jl +++ b/src/PreProcessing/FrequencyFilterParameter.jl @@ -2,6 +2,7 @@ export AbstractFrequencyFilterParameter abstract type AbstractFrequencyFilterParameter <: AbstractMPIRecoParameters end export NoFrequencyFilterParameter +# TODO This requires numPeriodAverages and numPeriodGrouping and should use a freq. loading function from MPIFiles struct NoFrequencyFilterParameter <: AbstractFrequencyFilterParameter end function process(::Type{<:AbstractMPIRecoAlgorithm}, params::NoFrequencyFilterParameter, file::MPIFile) @@ -10,8 +11,9 @@ end export DirectSelectionFrequencyFilterParameters Base.@kwdef struct DirectSelectionFrequencyFilterParameters{T <: Union{Integer, CartesianIndex{2}}, FIT <: AbstractVector{T}} <: AbstractFrequencyFilterParameter - freqIndices::FIT + freqIndices::Union{Nothing, FIT} = nothing end +DirectSelectionFrequencyFilterParameters() = DirectSelectionFrequencyFilterParameters{CartesianIndex{2}, Vector{CartesianIndex{2}}}(nothing) function process(::Type{<:AbstractMPIRecoAlgorithm}, params::DirectSelectionFrequencyFilterParameters{T}, file::MPIFile) where T <: Integer nFreq = params.freqIndices nReceivers = rxNumChannels(file) @@ -67,3 +69,11 @@ function process(::Type{<:AbstractMPIRecoAlgorithm}, params::AbstractFrequencyFi kwargs = toKwargs(params, default = Dict{Symbol, Any}(:maxFreq => rxBandwidth(file), :recChannels => 1:rxNumChannels(file))) filterFrequencies(file; kwargs...) end + +export CompositeFrequencyFilterParameters +Base.@kwdef struct CompositeFrequencyFilterParameters{FS} <: AbstractFrequencyFilterParameter where FS <: AbstractFrequencyFilterParameter + filters::Vector{FS} +end +function process(algoT::Type{<:AbstractMPIRecoAlgorithm}, params::CompositeFrequencyFilterParameters, file::MPIFile) + return reduce(intersect, filter(!isnothing, map(p -> process(algoT, p, file), params.filters))) +end \ No newline at end of file diff --git a/test/Reconstruction.jl b/test/Reconstruction.jl index b535ed5..84b084a 100644 --- a/test/Reconstruction.jl +++ b/test/Reconstruction.jl @@ -160,4 +160,21 @@ c11d = reconstruct("SinglePatch", b; params..., freqFilter = DirectSelectionFrequencyFilterParameters(freqIndices = freq_components)) @test isapprox(arraydata(c11c), arraydata(c11d)) + # No given freqs should be same as normal SNR thresh + freqFilter = CompositeFrequencyFilterParameters([ + DirectSelectionFrequencyFilterParameters(), + SNRThresholdFrequencyFilterParameter(minFreq = params[:minFreq], SNRThresh = params[:SNRThresh], recChannels = params[:recChannels]) + ]) + c11e = reconstruct("SinglePatch", b; params..., freqFilter = freqFilter) + @test isapprox(arraydata(c11a), arraydata(c11e)) + + # Custom freqs should remove one channel + custom_freqs = filter(f -> f[2] == 2, freqs) + freqFilter = CompositeFrequencyFilterParameters([ + DirectSelectionFrequencyFilterParameters(freqIndices = custom_freqs), + SNRThresholdFrequencyFilterParameter(minFreq = params[:minFreq], SNRThresh = params[:SNRThresh], recChannels = params[:recChannels]) + ]) + c11f = reconstruct("SinglePatch", b; params..., freqFilter = freqFilter) + c11g = reconstruct("SinglePatch", b; params..., recChannels = 2:2) + @test isapprox(arraydata(c11f), arraydata(c11g)) end