Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix S allocation bug in rsa and outcome_map #627

Closed
wants to merge 28 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
6c0bdea
Make predec a vector input for consistency
Rosejoycrocker Dec 12, 2023
5c0fc65
Move calculation of zones and priority predecessor criteria into sepa…
Rosejoycrocker Dec 12, 2023
25b2c4a
Changes to avoid id mismatches when using new priority zones or prior…
Rosejoycrocker Dec 13, 2023
ebb1aaa
Change how `strong_pred` is input to `guided_location_selection`
Rosejoycrocker Dec 13, 2023
8598533
Fix and simplify zone criteria calculation
Rosejoycrocker Dec 15, 2023
ef98417
Change references to "sites" to "locations" in docs for `priority_zon…
Rosejoycrocker Dec 15, 2023
3fe8d9f
Fix bug in how `strong_pred` is calculated
Rosejoycrocker Dec 18, 2023
eacbaf9
Add weighting to zones criteria to vary how much predecessors vs bein…
Rosejoycrocker Dec 18, 2023
c27027a
Add location ids as input instead of changing size of `strong_pred`
Rosejoycrocker Dec 18, 2023
de982d6
Fix dimension mismatches and add to documentation
Rosejoycrocker Dec 19, 2023
e82b059
Simplify formulation of priority predecessor criteria and add docs
Rosejoycrocker Dec 19, 2023
f0e5b98
Fix how weight is added if a location sites within a zone (should be …
Rosejoycrocker Dec 19, 2023
048c51a
Update documentation in `priority_zones_criteria`
Rosejoycrocker Dec 19, 2023
55afad7
Add tests for priority predecessor and zones criteria + update decisi…
Rosejoycrocker Dec 19, 2023
b853cd4
Change default weighting for zone criteria to equal for strongest sou…
Rosejoycrocker Dec 20, 2023
7f010d2
Add new test domain
Rosejoycrocker Dec 7, 2023
5a08a62
Update `datapackage.json`
Rosejoycrocker Dec 7, 2023
3d92e82
Fix residual reference to Moore domain, add new line at end of file a…
Rosejoycrocker Dec 11, 2023
afdc60f
Change `Example_domain` to `Test_domain` and change all references to…
Rosejoycrocker Dec 11, 2023
a34c253
Remove `Example_domain` remnants after renaming
Rosejoycrocker Dec 13, 2023
096f33a
Add "IterTools" in weak dependency list for use in testing
Rosejoycrocker Dec 14, 2023
230679b
Add IterTools to extras instead of weak dependencies
Rosejoycrocker Dec 18, 2023
2c45e89
Adjust listing to alphabetical order
ConnectedSystems Dec 19, 2023
3b8299c
Fix set_factor_bounds! out of bounds for discrete factors
Zapiano Dec 13, 2023
c7644e2
Consolidate sampling related methods into `sampling.jl`
ConnectedSystems Dec 15, 2023
c99e4b8
Adjust definition of S in RSA so that maximum S is used to define the…
Rosejoycrocker Dec 6, 2023
1d6f7af
Apply same changes for `outcome_map`, so that input S is still used f…
Rosejoycrocker Dec 6, 2023
88e125d
Formatting
Rosejoycrocker Jan 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added examples/Example_domain/DHWs/dhwRCP45.nc
Binary file not shown.
Binary file added examples/Example_domain/DHWs/dhwRCP45.nc~main
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file added examples/Example_domain/waves/wave_RCP45.nc~main
Binary file not shown.
205 changes: 113 additions & 92 deletions src/analysis/sensitivity.jl

Large diffs are not rendered by default.

308 changes: 190 additions & 118 deletions src/decision/dMCDA.jl

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/decision/location_selection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ function _location_selection(
rankingsin,
in_conn[site_ids],
out_conn[site_ids],
strong_pred[site_ids]
strong_pred,
)

return ranks[:, 2:3]
Expand Down
2 changes: 1 addition & 1 deletion src/ecosystem/connectivity.jl
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ function connectivity_strength(TP_base::AbstractMatrix{Float64})::NamedTuple
C2 = outdegree_centrality(g)

# For each node, find strongly connected predecessor (by number of connections)
strong_pred = zeros(Int64, size(C1)...)
strong_pred = zeros(Int64, (size(C1)...))
for v_id in vertices(g)
incoming = inneighbors(g, v_id)

Expand Down
5 changes: 4 additions & 1 deletion src/scenario.jl
Original file line number Diff line number Diff line change
Expand Up @@ -569,6 +569,9 @@ function run_model(domain::Domain, param_set::NamedDimsArray, corals::DataFrame,
# Pre-allocate rankings
rankings = [depth_priority zeros(Int, length(depth_priority)) zeros(Int, length(depth_priority))]

priority_locations = domain.sim_constants.priority_sites
priority_zones = domain.sim_constants.priority_sites

# Prep site selection
mcda_vars = DMCDA_vars(domain, param_set, depth_priority, sum(C_cover[1, :, :], dims=1), area_to_seed)

Expand Down Expand Up @@ -699,7 +702,7 @@ function run_model(domain::Domain, param_set::NamedDimsArray, corals::DataFrame,
rankings,
in_conn[mcda_vars.site_ids],
out_conn[mcda_vars.site_ids],
strong_pred[mcda_vars.site_ids],
strong_pred,
)

# Log site ranks
Expand Down
202 changes: 100 additions & 102 deletions test/mcda.jl
Original file line number Diff line number Diff line change
@@ -1,33 +1,35 @@
using Test
using Distributions
using ADRIA: mcda_normalize, create_decision_matrix, create_seed_matrix, create_fog_matrix


@testset "Create decision matrix" begin
using ADRIA.decision:
mcda_normalize,
create_decision_matrix,
create_seed_matrix,
create_fog_matrix,
priority_location_criteria,
priority_zones_criteria

function create_test_decision_matrix(n_sites::Int64, risk_tol::Float64)
# Combine decision criteria into decision matrix A
site_ids = collect(1:n_sites)
area = rand(Uniform(200.0, 1000.0), n_sites)
centr_out = rand(Uniform(0.0, 1.0), n_sites)
centr_in = rand(Uniform(0.0, 1.0), n_sites)
dam_prob = rand(Uniform(0.0, 1.0), n_sites)
heat_stress_prob = rand(Uniform(0.0, 1.0), n_sites)

# Dummy data to create decision matrix from
n_sites = 5
area = [1000.0, 800.0, 600.0, 200.0, 200.0]
centr_out = [1.0, 0.5, 0.5, 0.5, 0.5]
centr_in = [0.1, 0.0, 0.3, 0.1, 0.1]
dam_prob = [0.05, 0.1, 0.1, 0.5, 0.0]
heat_stress_prob = [0.05, 0.1, 0.1, 0.5, 0.0]
zones_criteria = [1.0, 1.33, 0.333, 1.0, 0.333]
site_depth = [5.0, 5.2, 7.1, 6.3, 8.6]
zones = [fill("Good", n_sites - 2)..., fill("Bad", 2)...]
site_depth = rand(Uniform(5.0, 10.0), n_sites)
strong_pred = rand(1:n_sites, n_sites)

# Dummy priority predecessors
priority_sites = zeros(n_sites)
predec = zeros(n_sites, 3)
predec[:, 1:2] .= rand(n_sites, 2)
predprior = predec[in.(predec[:, 1], [priority_sites']), 2]
predprior = [x for x in predprior if !isnan(x)]
predec[predprior, 3] .= 1.0
risk_tol = 0.8

predec = priority_location_criteria(strong_pred, [1, 2], site_ids)
zones_criteria = priority_zones_criteria(strong_pred, zones, ["Good"], site_ids)
Main.@infiltrate
prop_cover = [0.3, 0.5, 0.9, 0.6, 0.0]
max_cover = [0.8, 0.75, 0.95, 0.7, 0.0]
leftover_space = (max_cover .- prop_cover) .* area

k_area = max_cover .* area
leftover_space = (max_cover .- prop_cover) .* area
A, filtered = create_decision_matrix(
collect(1:n_sites),
centr_in,
Expand All @@ -40,55 +42,27 @@ using ADRIA: mcda_normalize, create_decision_matrix, create_seed_matrix, create_
zones_criteria,
risk_tol,
)
return A, filtered, k_area
end
@testset "Create decision matrix" begin
n_sites = 5
risk_tol = 0.8

A, filtered, k_area = create_test_decision_matrix(n_sites, risk_tol)

@test !any(isnan.(A)) || "NaNs found in decision matrix"
@test !any(isinf.(A)) || "Infs found in decision matrix"

@test A[end, 6] == 0.0 || "Site with 0 max cover should be ignored but was not"
end


@testset "MCDA seed matrix creation" begin
wtconseedout, wtconseedin, wt_waves, wt_heat, wt_predec_seed, wt_zones_seed, wt_lo_cover, wt_depth_seed = [
1.0, 1.0, 0.7, 1.0, 0.6, 0.6, 0.6, 0.7
]

# Combine decision criteria into decision matrix A
n_sites = 5
area = [1000.0, 800.0, 600.0, 200.0, 200.0]
centr_out = [1.0, 0.5, 0.5, 0.5, 0.5]
centr_in = [0.1, 0.0, 0.3, 0.1, 0.1]
dam_prob = [0.05, 0.1, 0.1, 0.5, 0.0]
heat_stress_prob = [0.05, 0.1, 0.1, 0.5, 0.0]
zones_criteria = [1.0, 1.33, 0.333, 1.0, 0.333]
site_depth = [5.0, 5.2, 7.1, 6.3, 8.6]

# Dummy priority predecessors
priority_sites = zeros(n_sites)
predec = zeros(n_sites, 3)
predec[:, 1:2] .= rand(n_sites, 2)
predprior = predec[in.(predec[:, 1], [priority_sites']), 2]
predprior = [x for x in predprior if !isnan(x)]
predec[predprior, 3] .= 1.0
risk_tol = 0.8

sum_cover = [0.3, 0.5, 0.9, 0.6, 0.0]
max_cover = [0.8, 0.75, 0.95, 0.7, 0.0]

leftover_space = (max_cover .- prop_cover) .* area
A, filtered = create_decision_matrix(
collect(1:n_sites),
centr_in,
centr_out,
leftover_space,
dam_prob,
heat_stress_prob,
site_depth,
predec,
zones_criteria,
0.8,
wtconseedout, wtconseedin, wt_waves, wt_heat, wt_predec_seed, wt_zones_seed, wt_lo_cover, wt_depth_seed = rand(
Uniform(0.0, 1.0),
8,
)

A, filtered, k_area = create_test_decision_matrix(5, 1.0)
min_area = 20.0
SE, wse = create_seed_matrix(
A,
Expand All @@ -104,55 +78,20 @@ end
)

@test (sum(filtered)) == size(A, 1) || "Site where heat stress > risk_tol not filtered out"
@test size(SE, 1) == n_sites - 2 ||
@test size(SE, 1) == sum(A[:, 8] .> min_area) ||
"Sites where space available < min_area not filtered out"
end

@testset "MCDA fog matrix creation" begin
wt_conn_fog, wt_waves, wt_heat, wt_predec_fog, wt_zones_fog, wt_hi_cover = [
1.0, 0.7, 1.0, 0.6, 0.6, 0.6
]

# Combine decision criteria into decision matrix A
n_sites = 5
area = [1000.0, 800.0, 600.0, 200.0, 200.0]
centr_out = [1.0, 0.5, 0.5, 0.5, 0.5]
centr_in = [0.1, 0.0, 0.3, 0.1, 0.1]
dam_prob = [0.05, 0.1, 0.1, 0.5, 0.0]
heat_stress_prob = [0.05, 0.1, 0.1, 0.5, 0.0]
zones_criteria = [1.0, 1.33, 0.333, 1.0, 0.333]
site_depth = [5.0, 5.2, 7.1, 6.3, 8.6]

# Dummy priority predecssors
priority_sites = zeros(n_sites)
predec = zeros(n_sites, 3)
predec[:, 1:2] .= rand(n_sites, 2)
predprior = predec[in.(predec[:, 1], [priority_sites']), 2]
predprior = [x for x in predprior if !isnan(x)]
predec[predprior, 3] .= 1.0

prop_cover = [0.75, 0.5, 0.3, 0.7, 0.0]
max_cover = [0.8, 0.75, 0.6, 0.77, 0.0]
area_max_cover = max_cover .* area
leftover_space = (max_cover .- prop_cover) .* area

A, filtered = create_decision_matrix(
collect(1:n_sites),
centr_in,
centr_out,
leftover_space,
dam_prob,
heat_stress_prob,
site_depth,
predec,
zones_criteria,
0.8,
wt_conn_fog, wt_waves, wt_heat, wt_predec_fog, wt_zones_fog, wt_hi_cover = rand(
Uniform(0.0, 1.0), 6
)

n_sites = 5
A, filtered, k_area = create_test_decision_matrix(n_sites, 0.8)
SH, wsh = create_fog_matrix(
A,
k_area[filtered],
area_max_cover[filtered],
wt_conn_fog,
wt_waves,
wt_heat,
Expand All @@ -162,7 +101,7 @@ end
)

@test maximum(SH[:, 8]) ==
(maximum(area_max_cover[convert(Vector{Int64}, A[:, 1])] .- A[:, 8])) ||
(maximum(k_area[convert(Vector{Int64}, A[:, 1])] .- A[:, 8])) ||
"Largest site with most coral area should have highest score"
end

Expand All @@ -182,3 +121,62 @@ end
@test all((sqrt.(sum(norm_A .^ 2, dims=1)) .- 1.0) .< 0.0001) || "Decision matrix normalization not giving column sums = 1."
@test (sum(norm_w) - 1.0) <= 0.001 || "MCDA weights not summing to one."
end

@testset "Priority predecessor and zones criteria" begin
mcda_funcs = ADRIA.decision.mcda_methods()
n_site_int = 5

# Create simplistic set of 8 sites
# Site 1 is the strongest predecessor for 2, 3, 4
# Site 5 is the strongest predecessor for sites 4, 5, 6
site_ids = collect(1:8)
n_sites = length(site_ids)
strong_pred = [0; 1; 1; 1; 0; 5; 5; 5]

# If 2,3,4 are the priority sites, site 1 should be selected first
priority_sites = [2, 3, 4]

priority_sites_crit = ADRIA.decision.priority_location_criteria(
strong_pred, priority_sites, site_ids
)
@test findall(priority_sites_crit .> 0)... == 1 ||
"The priority zones criteria is valuing sites which are not the strongest predecessor for priority sites"
zones = [
"DarkBlue"
"DarkBlue"
"DarkBlue"
"Pink"
"DarkBlue"
"DarkBlue"
"DarkBlue"
"Pink"
]

priority_zones_crit = ADRIA.decision.priority_zones_criteria(
strong_pred, zones, ["Pink"], site_ids
)
@test all(findall(priority_zones_crit .> 0) .== [1, 4, 5, 8]) ||
"Some sites which are priority zones or strongest predecessor to priority zones have zero valued zone criteria."

zones = [
"Black"
"Black"
"Black"
"Pink"
"DarkBlue"
"Black"
"Black"
"Pink"
]

priority_zones_crit = ADRIA.decision.priority_zones_criteria(
strong_pred, zones, ["Pink", "DarkBlue"], site_ids
)
@test findall(
priority_zones_crit .== minimum(priority_zones_crit[priority_zones_crit .!= 0.0])
)[1] == 1 ||
"Strongest predecessor site to priority zone in non-priority zone should have smallest non-zero value."

@test all(findall(priority_zones_crit .== maximum(priority_zones_crit)) == [4, 8]) ||
"Highest priority zone sites should have highest value in the zone criteria."
end
1 change: 1 addition & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,7 @@ include("io/inputs.jl")
include("metrics.jl")
include("sampling.jl")
include("seeding.jl")
include("mcda.jl")
include("site_selection.jl")
include("spatial_clustering.jl")
include("spec.jl")
Expand Down