Skip to content

Commit

Permalink
Merge pull request #16 from awesome-spectral-indices/fm/tests
Browse files Browse the repository at this point in the history
Finalizing testing structure
  • Loading branch information
MartinuzziFrancesco authored Jan 15, 2024
2 parents 174cd67 + c4a74e6 commit 6290733
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 107 deletions.
7 changes: 2 additions & 5 deletions src/axioms.jl
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,13 @@ function SpectralIndex(index::Dict)
end

function (si::SpectralIndex)(args::Number...)
arg_type = typeof(first(args))
parsed_formula = Meta.parse(si.formula)
expr = _build_function(si.short_name, parsed_formula, Symbol.(si.bands)...)
result = Base.invokelatest(expr, args...) ## to deal with for performance
return result
return arg_type(result)
end

#function (si::SpectralIndex)(args::AbstractArray...)
# return si.(args...)
#end

function Base.show(io::IO, index::SpectralIndex)
println(io, index.short_name, ": ", index.long_name)
println(io, "Application domain: ", index.application_domain)
Expand Down
24 changes: 14 additions & 10 deletions src/compute_index.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,10 @@ julia> compute_index(
```
"""
function compute_index(index::String, params=nothing, online::Bool=false; kwargs...)
indices = _create_indices(online)
function compute_index(
index::String, params=nothing, online::Bool=false; indices=indices, kwargs...
)
#indices = _create_indices(online)
names = keys(indices)
@assert index in names "$index is not a valid Spectral Index!"

Expand All @@ -66,15 +68,15 @@ function compute_index(index::String, params=nothing, online::Bool=false; kwargs
return results
end

function compute_index(index::String, params::Dict; indices=_create_indices())
function compute_index(index::String, params::Dict; indices=indices)
_check_params(indices[index], params)
params = _order_params(indices[index], params)
result = _compute_index(indices[index], params...)

return result
end

function compute_index(index::String, params::DataFrame; indices=_create_indices())
function compute_index(index::String, params::DataFrame; indices=indices)
# Convert DataFrame to a dictionary for each row and compute the index
results = [
compute_index(index, Dict(zip(names(params), row)); indices=indices) for
Expand All @@ -87,15 +89,17 @@ end

## TODO: simplify even further
# this is same function contente as dispatch on Dict
function compute_index(index::String, params::YAXArray; indices=_create_indices())
function compute_index(index::String, params::YAXArray; indices=indices)
_check_params(indices[index], params)
params = _order_params(indices[index], params)
result = _compute_index(indices[index], params...)
return result
end

function compute_index(index::Vector{String}, params=nothing, online::Bool=false; kwargs...)
indices = _create_indices(online)
function compute_index(
index::Vector{String}, params=nothing, online::Bool=false; indices=indices, kwargs...
)
#indices = _create_indices(online)
names = keys(indices)
for idx in index
@assert idx in names "$index is not a valid Spectral Index!"
Expand All @@ -112,7 +116,7 @@ end

# TODO: return results in a matrix columnswise
#multi_result = compute_index(["NDVI", "SAVI"], N = fill(0.643, 5), R = fill(0.175, 5), L = fill(0.5, 5))
function compute_index(index::Vector{String}, params::Dict; indices=_create_indices())
function compute_index(index::Vector{String}, params::Dict; indices=indices)
results = []

for (nidx, idx) in enumerate(index)
Expand All @@ -124,7 +128,7 @@ function compute_index(index::Vector{String}, params::Dict; indices=_create_indi
return results
end

function compute_index(index::Vector{String}, params::DataFrame; indices=_create_indices())
function compute_index(index::Vector{String}, params::DataFrame; indices=indices)
# Similar conversion and computation for a vector of indices
result_dfs = DataFrame()
for idx in index
Expand All @@ -136,7 +140,7 @@ function compute_index(index::Vector{String}, params::DataFrame; indices=_create
return result_dfs
end

function compute_index(index::Vector{String}, params::YAXArray; indices=_create_indices())
function compute_index(index::Vector{String}, params::YAXArray; indices=indices)
results = []
for (nidx, idx) in enumerate(index)
res_tmp = compute_index(idx, params; indices=indices)
Expand Down
43 changes: 29 additions & 14 deletions test/compute_index.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@ using YAXArrays
expected_ndvi_value_f64 = 0.5721271393643031
expected_savi_value_f64 = 0.5326251896813354

@testset "Basic Functionality" begin
@test compute_index("NDVI"; N=0.643, R=0.175) == expected_ndvi_value_f64
types = [Float64, Float32, Float16]

@testset "Basic Functionality" for T in types
@test compute_index("NDVI"; N=T(0.643), R=T(0.175)) T(expected_ndvi_value_f64) atol = eps(
T
)
end

@testset "Type Handling" begin
@test compute_index("NDVI"; N=fill(0.643, 5), R=fill(0.175, 5)) isa Array
@testset "Type Handling" for T in types
@test compute_index("NDVI"; N=fill(T(0.643), 5), R=fill(T(0.175), 5)) isa Array{T,1}
end

# @testset "Corner Cases" begin
Expand All @@ -22,48 +26,59 @@ end
@test_throws AssertionError compute_index("InvalidIndex"; N=0.5, R=0.5)
end

@testset "Multiple Indices" begin
results = compute_index(["NDVI", "SAVI"]; N=0.643, R=0.175, L=0.5)
@testset "Multiple Indices" for T in types
results = compute_index(["NDVI", "SAVI"]; N=T(0.643), R=T(0.175), L=T(0.5))
@test length(results) == 2
@test results[1] == expected_ndvi_value_f64
@test results[2] == expected_savi_value_f64
@test results[1] T(expected_ndvi_value_f64) atol = eps(T)
@test results[2] T(expected_savi_value_f64) atol = eps(T)
end

dfn_single = DataFrame(; N=[0.643, 0.56])
dfr_single = DataFrame(; R=[0.175, 0.22])
dfl_single = DataFrame(; L=[0.5, 0.4])
#dfn_single = DataFrame(; N=[0.643, 0.56])
#dfr_single = DataFrame(; R=[0.175, 0.22])
#dfl_single = DataFrame(; L=[0.5, 0.4])

@testset "DataFrame Tests" begin
@testset "DataFrame Tests" for T in types
@testset "Single Index as Params" begin
df_single = DataFrame(; N=[0.643, 0.56], R=[0.175, 0.22])
df_single = DataFrame(; N=T[0.643, 0.56], R=T[0.175, 0.22])
result_single = compute_index("NDVI", df_single)
@test size(result_single, 1) == 2
@test size(result_single, 2) == 1
@test names(result_single) == ["NDVI"]
@test typeof(result_single[!, "NDVI"][1]) == T
end

@testset "Single Index as kwargs" begin
dfn_single = DataFrame(; N=T[0.643, 0.56])
dfr_single = DataFrame(; R=T[0.175, 0.22])
result_single2 = compute_index("NDVI"; N=dfn_single, R=dfr_single)
@test size(result_single2, 1) == 2
@test size(result_single2, 2) == 1
@test names(result_single2) == ["NDVI"]
@test typeof(result_single2[!, "NDVI"][1]) == T
end

@testset "Multiple Indices as Params" begin
df_multiple = DataFrame(; N=[0.643, 0.56], R=[0.175, 0.22], L=[0.5, 0.4])
df_multiple = DataFrame(; N=T[0.643, 0.56], R=T[0.175, 0.22], L=T[0.5, 0.4])
result_multiple = compute_index(["NDVI", "SAVI"], df_multiple)
@test size(result_multiple, 1) == 2
@test size(result_multiple, 2) == 2
@test names(result_multiple) == ["NDVI", "SAVI"]
@test typeof(result_multiple[!, "NDVI"][1]) == T
@test typeof(result_multiple[!, "SAVI"][1]) == T
end

@testset "Multiple Indices as kwargs" begin
dfn_single = DataFrame(; N=T[0.643, 0.56])
dfr_single = DataFrame(; R=T[0.175, 0.22])
dfl_single = DataFrame(; L=T[0.5, 0.4])
result_multiple2 = compute_index(
["NDVI", "SAVI"]; N=dfn_single, R=dfr_single, L=dfl_single
)
@test size(result_multiple2, 1) == 2
@test size(result_multiple2, 2) == 2
@test names(result_multiple2) == ["NDVI", "SAVI"]
@test typeof(result_multiple2[!, "NDVI"][1]) == T
@test typeof(result_multiple2[!, "SAVI"][1]) == T
end
end

Expand Down
105 changes: 35 additions & 70 deletions test/compute_kernel.jl
Original file line number Diff line number Diff line change
@@ -1,85 +1,50 @@
using Test
using SpectralIndices
using DataFrames
using YAXArrays

# define data structures
# Number
a, b, c, p, sigma = 2, 3, 1, 2, 5
types = [Float64, Float32, Float16]

# Array
a_v, b_v, c_v, p_v, sigma_v = [1, 2, 3], [4, 5, 6], [1, 1, 1], [2, 2, 2], [5, 5, 5]
@testset "Tests for linear, poly, and RBF functions" begin
for T in types
a, b, c, p, sigma = T(2), T(3), T(1), T(2), T(5)
a_v, b_v, c_v, p_v, sigma_v = T.([1, 2, 3]),
T.([4, 5, 6]), T.([1, 1, 1]), T.([2, 2, 2]),
T.([5, 5, 5])
df = DataFrame(;
a=T.([1, 2]), b=T.([3, 4]), c=T.([1, 1]), p=T.([2, 2]), sigma=T.([5, 5])
)

# Dataframe
df = DataFrame(; a=[1, 2], b=[3, 4], c=[1, 1], p=[2, 2], sigma=[5, 5])
@testset "Tests for linear function with type $T" begin
@test linear(a, b) == T(6)

# YAXArray
axes = (Dim{:Lon}(1:5), Dim{:Lat}(1:5), Dim{:Time}(1:10))
a_yaxa = fill(0.643, (5, 5, 10))
b_yaxa = fill(0.175, (5, 5, 10))
c_yaxa = fill(0.5, (5, 5, 10))
p_yaxa = fill(0.5, (5, 5, 10))
sigma_yaxa = fill(0.5, (5, 5, 10))
@test all(linear(a_v, b_v) .== T.([4, 10, 18]))

ads = YAXArray(axes, a_yaxa)
bds = YAXArray(axes, b_yaxa)
cds = YAXArray(axes, c_yaxa)
pds = YAXArray(axes, p_yaxa)
sigmads = YAXArray(axes, sigma_yaxa)
@test eachcol(linear(df)) == eachcol(DataFrame(; linear=T.([3, 8])))
end

yaxa = concatenatecubes(
[ads, bds, cds, pds, sigmads], Dim{:Variables}(["a", "b", "c", "p", "sigma"])
)
@testset "Tests for poly function with type $T" begin
@test poly(a, b, c, p) == T(49)

# testing
@testset "Tests for linear function" begin
# Test with numbers
@test linear(a, b) == 6
expected_result = T.([(1 * 4 + 1)^2, (2 * 5 + 1)^2, (3 * 6 + 1)^2])
@test all(poly(a_v, b_v, c_v, p_v) .== expected_result)

# Test with arrays
@test all(linear(a_v, b_v) .== [4, 10, 18])
df_expected = DataFrame(; poly=T.([(1 * 3 + 1)^2, (2 * 4 + 1)^2]))
@test eachcol(poly(df)) == eachcol(df_expected)
end

# test with dataframes
@test eachcol(linear(df)) == eachcol(DataFrame(; linear=[3, 8]))
@testset "Tests for RBF function with type $T" begin
expected_number_result = exp((-1.0 * (a - b)^2.0) / (2.0 * sigma^2.0))
@test RBF(a, b, sigma) expected_number_result

# test with yaxarrays
@test all(linear(yaxa) .== YAXArray(axes, fill(0.112525, 5, 5, 10)))
end

@testset "Tests for poly function" begin
# Test with numbers
@test poly(a, b, c, p) == 49

# Test with arrays
expected_result = [(1 * 4 + 1)^2, (2 * 5 + 1)^2, (3 * 6 + 1)^2]
@test all(poly(a_v, b_v, c_v, p_v) .== expected_result)

# test with dataframes
df_expected = DataFrame(; poly=[(1 * 3 + 1)^2, (2 * 4 + 1)^2])
@test eachcol(poly(df)) == eachcol(df_expected)

# Test with yaxarrays
yaxa_expected = fill((0.643 * 0.175 + 0.5)^0.5, (5, 5, 10))
@test all(poly(yaxa) .== YAXArray(axes, yaxa_expected))
end

@testset "Tests for RBF function" begin
# Test with numbers
expected_number_result = exp((-1.0 * (a - b)^2.0) / (2.0 * sigma^2.0))
@test RBF(a, b, sigma) expected_number_result

# Test with arrays
expected_array_result =
exp.((-1.0 .* ((a_v .- b_v) .^ 2.0)) ./ (2.0 .* (sigma_v .^ 2.0)))
@test all(RBF(a_v, b_v, sigma_v) .≈ expected_array_result)

# Test with dataframes
df_expected = DataFrame(;
RBF=exp.((-1.0 .* ((df.a .- df.b) .^ 2.0)) ./ (2.0 .* (df.sigma .^ 2.0)))
)
@test eachcol(RBF(df)) == eachcol(df_expected)
expected_array_result =
exp.((-1.0 .* ((a_v .- b_v) .^ 2.0)) ./ (2.0 .* (sigma_v .^ 2.0)))
@test all(RBF(a_v, b_v, sigma_v) .≈ expected_array_result)

# Test with yaxarrays
yaxa_expected =
exp.((-1.0 .* ((a_yaxa .- b_yaxa) .^ 2.0)) ./ (2.0 .* (sigma_yaxa .^ 2.0)))
@test all(RBF(yaxa) .== YAXArray(axes, yaxa_expected))
df_expected = DataFrame(;
RBF=exp.((-1.0 .* ((df.a .- df.b) .^ 2.0)) ./ (2.0 .* (df.sigma .^ 2.0)))
)
@test eachcol(RBF(df)) == eachcol(df_expected)
end
end
end
8 changes: 8 additions & 0 deletions test/qa.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using SpectralIndices
using JuliaFormatter: JuliaFormatter
#using JET: JET
using Aqua: Aqua

Aqua.test_all(SpectralIndices; ambiguities=false, deps_compat=(check_extras = false))
@test JuliaFormatter.format(SpectralIndices; verbose=false, overwrite=false)
#JET.test_package(SpectralIndices; target_defined_modules=true)
10 changes: 2 additions & 8 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
using SafeTestsets
using Test
using SpectralIndices
using JuliaFormatter: JuliaFormatter
#using JET: JET
using Aqua: Aqua

@testset "Quality Assurance" begin
Aqua.test_all(SpectralIndices; ambiguities=false, deps_compat=(check_extras=false,))
@test JuliaFormatter.format(SpectralIndices; verbose=false, overwrite=false)
#JET.test_package(SpectralIndices; target_defined_modules=true)
@safetestset "Quality Assurance" begin
include("qa.jl")
end

@safetestset "Axioms" begin
Expand Down

0 comments on commit 6290733

Please sign in to comment.