Skip to content

Commit

Permalink
Merge pull request #39 from awesome-spectral-indices/fm/mt
Browse files Browse the repository at this point in the history
Even more tests
  • Loading branch information
MartinuzziFrancesco authored Feb 20, 2024
2 parents 1c8f1de + a9ead90 commit ec6f586
Show file tree
Hide file tree
Showing 8 changed files with 222 additions and 24 deletions.
11 changes: 3 additions & 8 deletions ext/SpectralIndicesDataFramesExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,12 @@ end
function SpectralIndices.load_dataset(
dataset::String, ::Type{T}
) where {T<:DataFrame}
datasets = Dict("sentinel" => "S2_10m.json", "spectral" => "spectral.json")
datasets = Dict("spectral" => "spectral.json")

if dataset in keys(datasets)
nothing
else
error("Dataset name not valid. Datasets available: sentinel and spectral")
error("Dataset name not valid. Datasets available for DataFrames: spectral")
end

ds = SpectralIndices._load_json(datasets[dataset])
Expand All @@ -76,25 +76,20 @@ function SpectralIndices.load_dataset(
push!(all_indices, parse(Int, idx))
end
end
all_indices = sort(collect(all_indices)) # Convert to sorted list

# Prepare a DataFrame with a specific row for each unique index
all_indices = sort(collect(all_indices))
df = DataFrame(; index=all_indices)

# Initialize columns based on the keys in `ds`
for col_name in keys(ds)
df[!, col_name] = Vector{Union{Missing,Any}}(missing, length(all_indices))
end

# Populate the DataFrame with actual values
for (col_name, col_data) in ds
for (idx, value) in col_data
row_idx = findfirst(==(parse(Int, idx)), all_indices)
df[row_idx, col_name] = value
end
end

# Optionally, remove the index column if it's not needed
select!(df, Not(:index))

return df
Expand Down
4 changes: 2 additions & 2 deletions ext/SpectralIndicesYAXArraysExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -92,12 +92,12 @@ end
function SpectralIndices.load_dataset(
dataset::String, ::Type{T}
) where {T<:YAXArray}
datasets = Dict("sentinel" => "S2_10m.json", "spectral" => "spectral.json")
datasets = Dict("sentinel" => "S2_10m.json")

if dataset in keys(datasets)
nothing
else
error("Dataset name not valid. Datasets available: sentinel and spectral")
error("Dataset name not valid. Datasets available for YAXArrays: sentinel")
end

ds = SpectralIndices._load_json(datasets[dataset])
Expand Down
9 changes: 1 addition & 8 deletions src/datasets.jl
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,4 @@ df_ds = SpectralIndices.load_dataset("spectral")
The current implementation expects the JSON files ("S2_10m.json" for "sentinel" and "spectral.json" for "spectral") to follow a specific format: a vector of vectors where each inner vector represents a band's data in a 300x300 spatial grid for the YAXArray version, or a suitable structure that can be directly converted into a DataFrame for the DataFrame version.
The files are already provided for examples in the package in the folder `data`.
"""
function load_dataset(dataset::String, ::Type{T}) where {T}
dfext = Base.get_extension(SpectralIndices, :SpectralIndicesDataFramesExt)
yaxaxext = Base.get_extension(SpectralIndices, :SpectralIndicesYAXArraysExt)

if isnothing(dfext) && isnothing(yaxaxext)
error("Load a library (DataFrames, YAXArrays) to use this function")
end
end
function load_dataset() end
13 changes: 13 additions & 0 deletions test/DataFrames/datasets.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Test
using SpectralIndices
using DataFrames

@testset "load_dataset: Valid Dataset Name Test" begin
df = load_dataset("spectral", DataFrame)
@test df isa DataFrame
@test !isempty(df)
end

@testset "load_dataset: Invalid Dataset Name Test" begin
@test_throws ErrorException load_dataset("invalidDatasetName", DataFrame)
end
13 changes: 13 additions & 0 deletions test/YAXArrays/datasets.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Test
using SpectralIndices
using YAXArrays

@testset "load_dataset: Valid Dataset Name Test" begin
df = load_dataset("sentinel", YAXArray)
@test df isa YAXArray
@test !isempty(df)
end

@testset "load_dataset: Invalid Dataset Name Test" begin
@test_throws ErrorException load_dataset("invalidDatasetName", YAXArray)
end
177 changes: 175 additions & 2 deletions test/compute_index.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,21 @@ using Test
using SpectralIndices
using YAXArrays
using Random
using Combinatorics
using StatsBase
Random.seed!(17)

convert_to_kwargs(dict) = Dict(Symbol(k) => v for (k, v) in dict)

@testset "Input Validation" begin
@testset "Input Validation: Invalid Index" begin
@test_throws AssertionError compute_index("InvalidIndex", N=0.5, R=0.5)
end

@testset "Built-in types compute_index tests: $idx_name" for (idx_name, idx) in indices
#@testset "Input Validation: Missing Band" begin
# @test_throws AssertionError compute_index("InvalidIndex", N=0.5, R=0.5)
#end

@testset "Built-in types compute_index single index tests: $idx_name" for (idx_name, idx) in indices
@testset "Single Values as Params" begin
if idx_name == "AVI" || idx_name == "TVI"
params = Dict("N" => 0.2, "R"=>0.1)
Expand Down Expand Up @@ -97,3 +103,170 @@ end
@test size(result) == (10,)
end
end

msi = custom_key_combinations(indices, 2, 200)

@testset "Built-in types compute_index multiple indices tests: $idxs" for idxs in msi

# Preprocessing to avoid "AVI" or "TVI" being the first index if there are multiple indices
if idxs[1] in ["AVI", "TVI"] && length(idxs) > 1
for i in 2:length(idxs)
if !(idxs[i] in ["AVI", "TVI"])
idxs[1], idxs[i] = idxs[i], idxs[1]
break
end
end
end

@testset "Single Values as Params for $idxs" begin
params = Dict()
for idx_name in idxs
idx = indices[idx_name]
if idx_name == "AVI" || idx_name == "TVI"
params["N"] = 0.2
params["R"] = 0.1
else
for band in idx.bands
params[band] = rand()
end
end
end
result = compute_index(idxs, params)
@test first(result) isa Float64
@test length(result) == 2
end

@testset "Single Values as Kwargs for $idxs" begin
params = Dict()
for idx_name in idxs
idx = indices[idx_name]
if idx_name == "AVI" || idx_name == "TVI"
params["N"] = 0.2
params["R"] = 0.1
else
for band in idx.bands
params[band] = rand()
end
end
end
result = compute_index(idxs; convert_to_kwargs(params)...)
@test first(result) isa Float64
@test length(result) == 2
end

@testset "Arrays as Params for $idxs" begin
params = Dict()
for idx_name in idxs
idx = indices[idx_name]
if idx_name == "AVI" || idx_name == "TVI"
params["N"] = fill(0.2, 10)
params["R"] = fill(0.1, 10)
else
for band in idx.bands
params[band] = rand(10)
end
end
end
result = compute_index(idxs, params)
@test result isa AbstractArray
@test length(result) == 2
@test length(first(result)) == 10
end

@testset "Arrays as Kwargs for $idxs" begin
params = Dict()
for idx_name in idxs
idx = indices[idx_name]
if idx_name == "AVI" || idx_name == "TVI"
params["N"] = fill(0.2, 10)
params["R"] = fill(0.1, 10)
else
for band in idx.bands
params[band] = rand(10)
end
end
end
result = compute_index(idxs; convert_to_kwargs(params)...)
@test result isa AbstractArray
@test length(result) == 2
@test length(first(result)) == 10
end

@testset "Matrices as Params for $idxs" begin
params = Dict()
for idx_name in idxs
idx = indices[idx_name]
if idx_name == "AVI" || idx_name == "TVI"
params["N"] = fill(0.2, 10, 10)
params["R"] = fill(0.1, 10, 10)
else
for band in idx.bands
params[band] = rand(10, 10)
end
end
end
result = compute_index(idxs, params)
@test first(result) isa Matrix
@test length(result) == 2
@test size(first(result)) == (10, 10)
end

@testset "Matrices as Kwargs for $idxs" begin
params = Dict()
for idx_name in idxs
idx = indices[idx_name]
if idx_name == "AVI" || idx_name == "TVI"
params["N"] = fill(0.2, 10, 10)
params["R"] = fill(0.1, 10, 10)
else
for band in idx.bands
params[band] = rand(10, 10)
end
end
end
result = compute_index(idxs; convert_to_kwargs(params)...)
@test first(result) isa Matrix
@test length(result) == 2
@test size(first(result)) == (10, 10)
end

@testset "NamedTuples as Params for $idxs" begin
dict_params = Dict()
for idx_name in idxs
idx = indices[idx_name]
if idx_name == "AVI" || idx_name == "TVI"
dict_params["N"] = fill(0.2, 10)
dict_params["R"] = fill(0.1, 10)
else
for band in idx.bands
dict_params[band] = rand(10)
end
end
end
# Convert the aggregated dict to NamedTuple
params = NamedTuple{Tuple(Symbol.(keys(dict_params)))}(values(dict_params))
result = compute_index(idxs, params)
@test result isa NamedTuple
@test size(first(values(result))) == (10,)
end

@testset "NamedTuples as Kwargs for $idxs" begin
dict_params = Dict()
for idx_name in idxs
idx = indices[idx_name]
if idx_name == "AVI" || idx_name == "TVI"
dict_params["N"] = fill(0.2, 10)
dict_params["R"] = fill(0.1, 10)
else
for band in idx.bands
dict_params[band] = rand(10)
end
end
end
# Convert the aggregated dict to NamedTuple for kwargs
params = NamedTuple{Tuple(Symbol.(keys(dict_params)))}(values(dict_params))
result = compute_index(idxs; params...)
@test result isa AbstractArray
@test size(first(result)) == (10,)
end
end
9 changes: 9 additions & 0 deletions test/compute_kernel.jl
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ end

params = Dict("a" => [1, 2], "b" => [3, 4])
@test compute_kernel(linear, params) == [3, 8]

params = (a=2, b=3)
@test compute_kernel(linear, params) == 6
end

# Test polynomial kernel
Expand All @@ -53,6 +56,9 @@ end

params = Dict("a" => [1, 2], "b" => [2, 3], "c" => [1, 1], "p" => [2, 3])
@test compute_kernel(poly, params) == [9, 343]

params = (a=2, b=3, c=1, p=2)
@test compute_kernel(poly, params) == 49
end

# Test RBF kernel
Expand All @@ -62,6 +68,9 @@ end

params = Dict("a" => [1, 2], "b" => [2, 1], "sigma" => [1, 2])
@test compute_kernel(RBF, params) [exp(-0.5), exp(-0.125)]

params = (a=1, b=2, sigma=1)
@test compute_kernel(RBF, params) exp(-0.5)
end
end

10 changes: 6 additions & 4 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ using Test
include("qa.jl")
end

@safetestset "Utils" begin
include("utils.jl")
include("DataFrames/datasets.jl")
include("YAXArrays/datasets.jl")
end

@safetestset "Axioms" begin
include("indices.jl")
include("platforms.jl")
Expand All @@ -24,7 +30,3 @@ end
include("DataFrames/compute_kernel.jl")
include("YAXArrays/compute_kernel.jl")
end

@safetestset "Utils" begin
include("utils.jl")
end

0 comments on commit ec6f586

Please sign in to comment.