From 6fa5853cc0126654515562d10f2c4835779ffa9a Mon Sep 17 00:00:00 2001 From: Rose Crocker Date: Mon, 20 Jan 2025 07:35:38 +1000 Subject: [PATCH] Add decision matrix visualisation test to `/test/mcda.jl` Should be moved to `site_selection.jl` later when all tests are passing Add additional testing to decision matrix visualisation tests Formatting --- ext/AvizExt/viz/spatial.jl | 2 +- src/scenario.jl | 5 +-- test/mcda.jl | 62 ++++++++++++++++++++++++++++++++++++++ test/site_selection.jl | 51 ------------------------------- 4 files changed, 66 insertions(+), 54 deletions(-) diff --git a/ext/AvizExt/viz/spatial.jl b/ext/AvizExt/viz/spatial.jl index 8ada21eb1..b8affb490 100644 --- a/ext/AvizExt/viz/spatial.jl +++ b/ext/AvizExt/viz/spatial.jl @@ -303,7 +303,7 @@ function ADRIA.viz.map!( opts::OPT_TYPE=DEFAULT_OPT_TYPE(), axis_opts::OPT_TYPE=set_axis_defaults(DEFAULT_OPT_TYPE()) ) - if length(rs.loc_data.site_id) != size(M, 1) + if length(rs.loc_data.site_id) != size(outputs_matrix, 1) error("Only unfiltered decision matrices can be plotted.") end diff --git a/src/scenario.jl b/src/scenario.jl index 032971b1a..f190ed532 100644 --- a/src/scenario.jl +++ b/src/scenario.jl @@ -1105,5 +1105,6 @@ function cyclone_mortality!( return nothing end -_loc_coral_cover(C_cover_t::Array{Float64,3}) = - dropdims(sum(C_cover_t; dims=(1, 2)); dims=(1, 2)) +function _loc_coral_cover(C_cover_t::Array{Float64,3}) + return dropdims(sum(C_cover_t; dims=(1, 2)); dims=(1, 2)) +end diff --git a/test/mcda.jl b/test/mcda.jl index 4271034cf..8b3c060f9 100644 --- a/test/mcda.jl +++ b/test/mcda.jl @@ -3,6 +3,11 @@ using ADRIA.Distributions using ADRIA.decision.JMcDM using ADRIA.decision: subtypes +if !@isdefined(ADRIA_DIR) + const ADRIA_DIR = pkgdir(ADRIA) + const TEST_DOMAIN_PATH = joinpath(ADRIA_DIR, "test", "data", "Test_domain") +end + @testset "Validate included MCDA methods" begin """ Identifies MCDA methods that pass a simple test to inform whether they should be included @@ -155,3 +160,60 @@ end @test dm.data == new_vals || "Failed to update criteria values by name" end + +@testset "Test decision matrix spatial plotting" begin + mcda_funcs = ADRIA.decision.mcda_methods() + + dom = ADRIA.load_domain(TEST_DOMAIN_PATH, 45) + N = 2^3 + scens = ADRIA.sample_selection(dom, N) # get scenario dataframe + scen = scens[1, :] + + # Get seeding preferences + seed_pref = ADRIA.decision.SeedPreferences(dom, scen) + + # Calculate criteria vectors + # Cover + sum_cover = vec(sum(dom.init_coral_cover; dims=1).data) + # DHWS + dhw_scens = dom.dhw_scens[:, :, Int64(scen["dhw_scenario"])] + plan_horizon = Int64(scen["plan_horizon"]) + decay = 0.99 .^ (1:(plan_horizon + 1)) .^ 2 + dhw_projection = ADRIA.decision.weighted_projection( + dhw_scens, 1, plan_horizon, decay, 75 + ) + # Connectivity + area_weighted_conn = dom.conn.data .* ADRIA.site_k_area(dom) + conn_cache = similar(area_weighted_conn) + in_conn, out_conn, network = ADRIA.connectivity_strength( + area_weighted_conn, sum_cover, conn_cache + ) + + # Create decision matrix + seed_decision_mat = ADRIA.decision.decision_matrix( + dom.loc_ids, + seed_pref.names; + seed_in_connectivity=in_conn, + seed_out_connectivity=out_conn, + seed_heat_stress=dhw_projection, + seed_coral_cover=sum_cover + ) + + # Get results from applying MCDA algorithm + crit_agg = ADRIA.decision.criteria_aggregated_scores( + seed_pref, seed_decision_mat, mcda_funcs[1] + ) + + # Don't plot constant criteria + is_const = Bool[length(x) == 1 for x in unique.(eachcol(seed_decision_mat.data))] + + @test all(.!isnan(crit_agg)) || "Criteria aggregate score contains NaNs." + @test all(.!isnan(seed_decision_mat)) || "Decision matrix contains NaNs." + @test all(seed_decision_mat .>= 0.0) || "Decision matrix containsnegative values." + + # Plot normalized scores and criteria as map + decision_mat_fig = ADRIA.viz.selection_criteria_map( + dom, seed_decision_mat[criteria=.!is_const], + crit_agg.scores ./ maximum(crit_agg.scores) + ) +end diff --git a/test/site_selection.jl b/test/site_selection.jl index 3b4a9a6e9..ddf02c7f2 100644 --- a/test/site_selection.jl +++ b/test/site_selection.jl @@ -89,54 +89,3 @@ end rank in 1:size(s_order, 1) ]) || "Ranking does not match mcda score ordering" end - -@testset "Test decision matrix spatial plotting" begin - dom = ADRIA.load_domain(TEST_DOMAIN_PATH, 45) - N = 2^3 - scens = ADRIA.sample_selection(dom, N) # get scenario dataframe - scen = scens[1, :] - - # Get seeding preferences - seed_pref = ADRIA.decision.SeedPreferences(dom, scen) - - # Calculate criteria vectors - # Cover - sum_cover = vec(sum(dom.init_coral_cover; dims=1).data) - # DHWS - dhw_scens = dom.dhw_scens[:, :, Int64(scen["dhw_scenario"])] - plan_horizon = Int64(scen["plan_horizon"]) - decay = 0.99 .^ (1:(plan_horizon + 1)) .^ 2 - dhw_projection = ADRIA.decision.weighted_projection( - dhw_scens, 1, plan_horizon, decay, 75 - ) - # Connectivity - area_weighted_conn = dom.conn.data .* ADRIA.site_k_area(dom) - conn_cache = similar(area_weighted_conn) - in_conn, out_conn, network = ADRIA.connectivity_strength( - area_weighted_conn, sum_cover, conn_cache - ) - - # Create decision matrix - seed_decision_mat = ADRIA.decision.decision_matrix( - dom.loc_ids, - seed_pref.names; - seed_in_connectivity=in_conn, - seed_out_connectivity=out_conn, - seed_heat_stress=dhw_projection, - seed_coral_cover=sum_cover - ) - - # Get results from applying MCDA algorithm - crit_agg = ADRIA.decision.criteria_aggregated_scores( - seed_pref, seed_decision_mat, mcda_funcs[1] - ) - - # Don't plot constant criteria - is_const = Bool[length(x) == 1 for x in unique.(eachcol(seed_decision_mat.data))] - - # Plot normalized scores and criteria as map - decision_mat_fig = ADRIA.viz.selection_criteria_map( - dom, seed_decision_mat[criteria=.!is_const], - crit_agg.scores ./ maximum(crit_agg.scores) - ) -end