ADRIA API
Metrics
ADRIA.metrics._absolute_juveniles Method
absolute_juveniles(X::AbstractArray{T,3}, coral_spec::DataFrame, k_area::AbstractVector{T})::AbstractArray{T,2} where {T<:Real}
absolute_juveniles(rs::ResultSet)::AbstractArray{<:Real,2}Juvenile coral cover in m².
Arguments
X: Raw model results for a single scenario. Dimensions (n_timesteps, n_group, n_sizes,
n_locations)
coral_spec: Coral spec DataFramek_area: The coral habitable area.
ADRIA.metrics._absolute_shelter_volume Method
absolute_shelter_volume(X::YAXArray{T,4}, k_area::Vector{T}, inputs::DataFrameRow)::AbstractArray{T} where {T<:Real}
absolute_shelter_volume(X::YAXArray{T,4}, k_area::Vector{T}, inputs::YAXArray)::AbstractArray{T} where {T<:Real}
absolute_shelter_volume(X::YAXArray{T,5}, k_area::Vector{T}, inputs::DataFrame)::AbstractArray{T} where {T<:Real}
absolute_shelter_volume(X::YAXArray{T,5}, k_area::Vector{T}, inputs::YAXArray)::AbstractArray{T} where {T<:Real}
absolute_shelter_volume(rs::ResultSet)Provide indication of shelter volume in volume of cubic meters.
The metric applies log-log linear models developed by Urbina-Barreto et al., [1] which uses colony diameter and planar area (2D metrics) to estimate shelter volume (a 3D metric).
Arguments
X: raw resultsk_area: area in m^2 for each sitemax_cover: maximum possible coral cover for each site (in percentage of loc_area)inputs: DataFrame of scenario inputs
References
- Urbina-Barreto, I., Chiroleu, F., Pinel, R., Fréchon, L., Mahamadaly, V., Elise, S., Kulbicki, M., Quod, J.-P., Dutrieux, E., Garnier, R., Henrich Bruggemann, J., Penin, L., & Adjeroud, M. (2021). Quantifying the shelter capacity of coral reefs using photogrammetric 3D modeling: From colonies to reefscapes. Ecological Indicators, 121, 107151. https://doi.org/10.1016/j.ecolind.2020.107151
ADRIA.metrics._collate_ranked_locs Method
_collate_ranked_locs(data::YAXArray)::Matrix{Int64}Collates number of ranked locations.
sourceADRIA.metrics._collate_ranks Method
_collate_ranks(rs, selected)Collates ranks into seed/fog ranking results into a common structure.
sourceADRIA.metrics._coral_diversity Method
coral_diversity(ce::AbstractArray{T})::AbstractArray{T} where {T}
coral_diversity(rs::ResultSet)::AbstractArray{T} where {T}Calculates coral diversity metric as the Gini-Simpson index. This is calculated from coral evenness (which is the inverse Simpson's index, 1/D) as 1 - 1/evenness, which is equivalent to 1 - D.
Arguments
ce: Coral evenness (inverse Simpson's index).rs: A ResultSet object.
ADRIA.metrics._coral_evenness Method
coral_evenness(r_taxa_cover::AbstractArray{T})::AbstractArray{T} where {T<:Real}
coral_evenness(rs::ResultSet)::AbstractArray{T} where {T}Calculates evenness across functional coral groups in ADRIA as a diversity metric. Inverse Simpsons diversity indicator.
References
- Hill, M. O. (1973).
Diversity and Evenness: A Unifying Notation and Its Consequences. Ecology, 54(2), 427-432. https://doi.org/10.2307/1934352
sourceADRIA.metrics._extract_axes_values Method
Helper method to extract pairs of YAXArray axes (names and their values).
sourceADRIA.metrics._get_ranks Method
_get_ranks(rs::ResultSet, intervention::Int64; kwargs...)Extracts results for a specific intervention (:seed or :fog)
sourceADRIA.metrics._juvenile_indicator Method
juvenile_indicator(X::AbstractArray{T}, coral_spec::DataFrame, k_area::Vector{Float64})::AbstractArray{T,2} where {T<:Real}
juvenile_indicator(rs::ResultSet)::AbstractArray{<:Real,2}Indicator for juvenile density (0 - 1), where 1 indicates the maximum theoretical density for juveniles have been achieved.
Arguments
X: Raw model results for a single scenario. Dimensions (n_timesteps, n_group, n_sizes,
n_locations).
coral_spec: Coral spec DataFrame.k_area: The coral habitable area.max_juvenile_density: Maximum density of juveniles defaulting to 51.8 juveniles / m²
Notes
Maximum density is 51.8 juveniles / m², where juveniles are defined as < 5cm diameter. See email correspondence from: Dr. A Thompson; to: Dr. K. Anthony Subject: RE: Max density of juvenile corals on the GBR Sent: Friday, 14 October 2022 2:58 PM
sourceADRIA.metrics._max_juvenile_area Function
_max_juvenile_area(coral_params::DataFrame, max_juv_density::Float64=51.8)Calculate the maximum possible area that can be covered by juveniles for a given m².
sourceADRIA.metrics._reef_biodiversity_condition_index Method
_reef_biodiviersity_condition_index(rs::ResultSet)ADRIA.metrics._reef_condition_index Method
reef_condition_index(ltmp_cover::AbstractArray, sv::AbstractArray, juves::AbstractArray,)::AbstractArray
reef_condition_index(ltmp_cover::AbstractArray, juves::AbstractArray, sv::AbstractArray, rubble::AbstractArray)::AbstractArray
reef_condition_index(rs::ResultSet)::AbstractArray{<:Real}
reef_condition_index(rs::ResultSet, rubble::AbstractArray)::AbstractArray{<:Real}Estimates a Reef Condition Index (RCI) using either the 3-metric version using relative cover, juveniles, shelter volume or the 4-metric versions with rubble added.
The RCI is a single value that indicates the condition of a reef.
Notes
Juveniles are made relative to maximum observed juvenile density (15.0/m²) See table 1 in reference 1.
Arguments
ltmp_cover: LTMP coral cover across all groupsjuves: Abundance of coral juveniles < 5 cm diametersv: Shelter volume based on coral sizes and abundancesrubble: Cover of rubble (optional)rs: A ResultSet object.
Returns
YAXArray[timesteps ⋅ locations ⋅ scenarios]
References
- Ryan F. Heneghan, Gabriela Scheufele, Yves-Marie Bozec et al. A framework to inform economic valuation of non-use benefits from coral-reef intervention efforts, 02 October 2025, PREPRINT (Version 1) available at Research Square [https://doi.org/10.21203/rs.3.rs-7644150/v1]
ADRIA.metrics._reef_fish_index Method
reef_fish_index(rc::AbstractArray)
reef_fish_index(rs::ResultSet)The Reef Fish Index (RFI) estimates fish biomass from relative coral cover.
A linear regression (developed by Dr. R. Heneghan, Queensland University of Technology) is used to indicate the relationship between coral cover and fish biomass. The regression was developed with digitized data from Figures 4a and 6b in Graham & Nash (2013; see [1]).
Values are provided ∈ [0, 1], where 1 indicates maximum fish biomass.
Note: Coral cover here is relative to coral habitable area (
Arguments
rc: Relative cover
Returns
YAXArray[timesteps ⋅ locations ⋅ scenarios], values in kg/km²
References
- Graham, N.A.J., Nash, K.L., 2013.
The importance of structural complexity in coral reef ecosystems. Coral Reefs 32, 315–326. https://doi.org/10.1007/s00338-012-0984-y
sourceADRIA.metrics._reef_tourism_index Method
reef_tourism_index(rc::AbstractArray{<:Real,3}, sv::AbstractArray{<:Real,3}, juves::AbstractArray{<:Real,3}, cots::AbstractArray{<:Real,3}, rubble::AbstractArray{<:Real,3})::AbstractArray
reef_tourism_index(rc::AbstractArray{<:Real,3}, ce::AbstractArray{<:Real,3}, sv::AbstractArray{<:Real,3}, juves::AbstractArray{<:Real,3})::AbstractArray
reef_tourism_index(rs::ResultSet, cots::YAXArray, rubble::YAXArray)::AbstractArray
reef_tourism_index(rs::ResultSet)::AbstractArrayEstimate tourism index.
This metric is a variation of the Reef Condition Index, but weighted by metrics known to be of importance to tourists. This version uses 5 metrics: relative cover, shelter volume, juvenile abundance, CoTS, and rubble.
Arguments
rs: ResultSetcots: Outbreak status of Crown-of-Thorns Starfishrubble: Cover of rubble
ADRIA.metrics._relative_cover Method
relative_cover(X::AbstractArray{<:Real}, loc_area::AbstractVector{<:Real})::AbstractArray{<:Real}
relative_cover(rs::ResultSet)::AbstractArray{<:Real}Indicate coral cover relative to available hard substrate (
Arguments
X: Matrix with dimensions (n_timesteps, n_functional_groups * n_size_classes,
n_locations) of raw model results (coral cover relative to available space)
Returns
Coral cover [0 - 1], relative to available
ADRIA.metrics._relative_juveniles Method
relative_juveniles(X::AbstractArray{T,3}, coral_spec::DataFrame)::AbstractArray{T,2} where {T<:Real}
relative_juveniles(rs::ResultSet)::AbstractArray{<:Real,2}Juvenile coral cover relative to the location's area.
Arguments
X: Raw model results for a single scenario. Dimensions (n_timesteps, n_group, n_sizes,
n_locations)
coral_spec: Coral spec DataFrame
ADRIA.metrics._relative_loc_taxa_cover Method
relative_loc_taxa_cover(X::AbstractArray{T}, k_area::Vector{T}, n_groups::Int64)::AbstractArray{T,3} where {T<:Real}Arguments
X: Raw model results for a single scenario. Dimensions (n_timesteps, n_group, n_sizes,
n_locations)
k_area: The coral habitable area.n_groups: Number of function coral groups.
Returns
Coral cover, grouped by taxa for the given scenario, for each timestep and location, relative to location k area.
sourceADRIA.metrics._relative_shelter_volume Method
relative_shelter_volume(X::AbstractArray{T,4}, k_area::Vector{T}, inputs::DataFrameRow)::AbstractArray{T} where {T<:Real}
relative_shelter_volume(X::AbstractArray{T,4}, k_area::Vector{T}, inputs::YAXArray)::AbstractArray{T} where {T<:Real}
relative_shelter_volume(X::AbstractArray{T,5}, k_area::Vector{T}, inputs::DataFrame)::AbstractArray{T} where {T<:Real}
relative_shelter_volume(X::AbstractArray{T,5}, k_area::Vector{T}, inputs::YAXArray)::AbstractArray{T} where {T<:Real}
relative_shelter_volume(rs::ResultSet)Provide indication of shelter volume relative to theoretical maximum volume for the area covered by coral.
The metric applies log-log linear models developed by Urbina-Barreto et al., [1] which uses colony diameter and planar area (2D metrics) to estimate shelter volume (a 3D metric).
where
Arguments
X: raw resultsk_area: area in m^2 for each sitescens: DataFrame of scenario inputs
Returns
Shelter volume relative to a theoretical maximum volume for the available
References
- Urbina-Barreto, I., Chiroleu, F., Pinel, R., Fréchon, L., Mahamadaly, V., Elise, S.,
Kulbicki, M., Quod, J.-P., Dutrieux, E., Garnier, R., Henrich Bruggemann, J., Penin, L., & Adjeroud, M. (2021). Quantifying the shelter capacity of coral reefs using photogrammetric 3D modeling: From colonies to reefscapes. Ecological Indicators, 121, 107151. https://doi.org/10.1016/j.ecolind.2020.107151
sourceADRIA.metrics._relative_taxa_cover Method
relative_taxa_cover(X::AbstractArray{<:Real}, k_area::Vector{<:Real}, n_groups::Int64)::AbstractArray{<:Real,2}
relative_taxa_cover(rs::ResultSet)::AbstractArray{<:Real,2}Relative coral cover grouped by groups summed up across all locations.
Arguments
X: Raw model results for a single scenario. Dimensions (n_timesteps, n_group, n_sizes,
n_locations).
k_area: The coral habitable area.n_groups: Number of function coral groups.
Returns
Coral cover, grouped by taxa for the given scenario, summed up across all locations, relative to total k area.
sourceADRIA.metrics._scenario_absolute_juveniles Method
scenario_absolute_juveniles(data::YAXArray, coral_spec::DataFrame, k_area::AbstractVector{<:Real}; kwargs...)::AbstractArray{<:Real}
scenario_absolute_juveniles(rs::ResultSet; kwargs...)::AbstractArray{<:Real}Calculate the mean absolute juvenile population for each scenario for the entire domain.
Arguments
aj: Raw data for a single scenario.k_area: K_area.rs: Resultset.
ADRIA.metrics._scenario_asv Method
scenario_asv(sv::YAXArray; kwargs...)::AbstractArray{<:Real}
scenario_asv(rs::ResultSet; kwargs...)::AbstractArray{<:Real}Calculate the mean absolute shelter volumes for each scenario for the entire domain.
Arguments
asv: Absolute shelter volume.rs: Resultset.
ADRIA.metrics._scenario_evenness Method
scenario_evenness(ev::YAXArray; kwargs...)::AbstractArray{<:Real}
scenario_evenness(rs::ResultSet; kwargs...)::AbstractArray{<:Real}Calculate the mean coral evenness for each scenario for the entire domain.
sourceADRIA.metrics._scenario_juvenile_indicator Method
scenario_juvenile_indicator(data::YAXArray, coral_spec::DataFrame, k_area::AbstractVector{<:Real}; kwargs...)::AbstractArray{<:Real}
scenario_juvenile_indicator(rs::ResultSet; kwargs...)::AbstractArray{<:Real}Determine juvenile indicator ∈ [0, 1], where 1 indicates maximum mean juvenile density (51.8) has been achieved.
Arguments
ji: Juvenile Indicator for each location.rs: Resultset.
ADRIA.metrics._scenario_rci Method
scenario_rci(rci::YAXArray, tac::YAXArray; kwargs...)
scenario_rci(rci::YAXArray, rubble::YAXArray; kwargs...)
scenario_rci(rs::ResultSet; kwargs...)Extract the total populated area of locations with Reef Condition Index of "Good" or higher for each scenario for the entire domain.
sourceADRIA.metrics._scenario_relative_cover Method
scenario_relative_cover(rs::ResultSet; kwargs...)::AbstractArray{<:Real}Calculate the mean relative coral cover for each scenario for the entire domain.
sourceADRIA.metrics._scenario_relative_juveniles Method
scenario_relative_juveniles(X::YAXArray{<:Real,3}, coral_spec::DataFrame, k_area::AbstractVector{<:Real}; kwargs...)::AbstractArray{<:Real}
scenario_relative_juveniles(rs::ResultSet; kwargs...)::YAXArrayCalculate the mean relative juvenile population for each scenario for the entire domain.
Arguments
X: Raw data for a single scenario.rs: Resultset.coral_spec: Coral spec DataFrame.k_area: K_area.
Examples
num_scens = 2^5
scens = ADRIA.sample(dom, num_scens)
_coral_spec = ADRIA.to_coral_spec(scens[1,:])
_k_area = loc_k_area(dom)
# X contains raw coral cover results for a single scenario
ADRIA.metrics.scenario_relative_juveniles(X, _coral_spec, _k_area)ADRIA.metrics._scenario_rfi Method
scenario_rfi(rfi::YAXArray; kwargs...) scenario_rfi(rs::ResultSet; kwargs...)
Calculate the mean Reef Fish Index (RFI) for each scenario for the entire domain.
sourceADRIA.metrics._scenario_rsv Method
scenario_rsv(sv::YAXArray; kwargs...)::AbstractArray{<:Real}
scenario_rsv(rs::ResultSet; kwargs...)::AbstractArray{<:Real}Calculate the mean relative shelter volumes for each scenario for the entire domain.
sourceADRIA.metrics._scenario_rti Method
scenario_rti(rs::ResultSet, cots::YAXArray, rubble::YAXArray; kwargs...)
scenario_rti(rs::ResultSet; kwargs)Calculate the mean Reef Tourism Index (RTI) for each scenario for the entire domain.
sourceADRIA.metrics._scenario_total_cover Method
scenario_total_cover(rs::ResultSet; kwargs...)::AbstractArray{<:Real}Calculate the mean absolute coral for each scenario for the entire domain.
Arguments
tac: Total absolute coverrs: ResultSet
ADRIA.metrics._summarize_inner Method
Barrier function: Val{NA}/Val{NK} allow Julia to specialize on ndims at compile time, eliminating per-iteration dynamic dispatch on view/metric calls.
sourceADRIA.metrics._total_absolute_cover Method
total_absolute_cover(relative_cover::AbstractArray{<:Real}, k_area::Vector{<:Real})::AbstractArray{<:Real}
total_absolute_cover(rs::ResultSet)::AbstractArray{<:Real}The Total Absolute Coral Cover. Sum of proportional area taken up by all corals, multiplied by the location area.
Arguments
relative_cover: Array with relative_coverk_area: Proportional area, with locations following the same order as given indicated inrelative_cover.
Returns
Absolute coral cover for a given location in m².
sourceADRIA.metrics._years_above_threshold Method
years_above_threshold(data::YAXArray{<:Real,2}; threshold::Real=0.1, kwargs...)::AbstractArray{<:Real}
years_above_threshold(data::YAXArray{<:Real,3}; threshold::Real=0.1, kwargs...)::AbstractArray{<:Real}Count the number of years a metric exceeded a threshold.
For 2D input (timesteps x scenarios): returns Vector[scenarios]. For 3D input (timesteps x locations x scenarios): returns Matrix[locations x scenarios].
Arguments
data: Metric values over time.threshold: Threshold value (default: 0.1).
ADRIA.metrics.axes_units Method
axes_units(axes_names::Union{Vector{Symbol},Tuple})::TupleGet units for each metric axis.
sourceADRIA.metrics.call_metric Method
call_metric(metric::Union{Function,Metric}, data::YAXArray, args...; kwargs...)Convenience method that slices the data in the specified manner.
Arguments
metric: Function, the metric function to apply to "raw" data.data: YAXArray, data to pass intometricargs: Additional positional arguments to pass intometrickwargs: Additional keyword arguments to pass intoslice_resultsdims: dummy keyword argument, not used but defined to allow use with other methods
ADRIA.metrics.deployed_locations Method
deployed_locations(rs::ResultSet; intervention::Symbol=:seed)::Vector{Int}Return the integer indices of locations that received at least one deployment of the given intervention type, across all timesteps and scenarios.
Arguments
rs: ResultSetintervention: Intervention type — one of:seed,:fog,:mc(default::seed)
Returns
Vector of 1-based integer location indices. Pass directly to metrics that accept a locations keyword argument, e.g.:
locs = ADRIA.metrics.deployed_locations(rs; intervention=:seed)
rc = ADRIA.metrics.scenario_relative_cover(rs; locations=locs)ADRIA.metrics.dims Method
dims(m::Metric)::TupleGet dimension names for a given outcome/metric.
sourceADRIA.metrics.dominates Method
dominates(x::Vector{<:Real}, y::Vector{<:Real})::VectorAdapted from: https://discourse.julialang.org/t/fast-optimized-non-dominated-sorting-algorithms/86793/7
Original function name is dominates2()
ADRIA.metrics.ensemble_loc_difference Method
ensemble_loc_difference(outcome::YAXArray{T,3}, scens::DataFrame; agg_metric::Union{Function,AbstractFloat}=median, diff_target=:guided, conf::Float64=0.95, rng::AbstractRNG=Random.GLOBAL_RNG)::YAXArray where {T}Mean bootstrapped difference (counterfactual - target) between some outcome aggregated for each location.
Arguments
outcome: Metric outcome with dimensions (:timesteps, :locations, :scenarios).scens: Scenarios DataFrame.agg_metric: Metric used to aggregate scenarios when comparing between counterfactual and
target. If it is an AbstractFloat between 0 and 1, it uses the agg_metric-th quantile. Defaults to median.
diff_target: Target group of scenarios to compare with. Valid options are:guidedand
:unguided. Defaults to :guided
conf: Percentile used for the confidence interval. Defaults to 0.95.rng: Pseudorandom number generator.
Example
# Load domain
dom = ADRIA.load_domain(path_to_domain, "<RCP>")
# Create scenarios
num_scens = 2^6
scens = ADRIA.sample(dom, num_scens)
# Run model
rs = ADRIA.run_scenarios(dom, scens, "45")
# Calculate difference to the counterfactual for given metric
_relative_cover = metrics.relative_cover(rs)
# Compute difference between guided and counterfactual using the 0.6-th quantile
gd_res = metrics.ensemble_loc_difference(r_cover, scens; agg_metric=0.6)
# Compute difference between unguided and counterfactual using the median
ug_res = metrics.ensemble_loc_difference(r_cover, scens; diff_target=:unguided)
# Plot maps of difference to the counterfactual
ADRIA.viz.map(rs, gd_res[summary=At(:agg_value)]; diverging=true)
ADRIA.viz.map(rs, ug_res[summary=At(:agg_value)]; diverging=true)Returns
Vector with bootstrapped difference (counterfactual - guided) for each location.
sourceADRIA.metrics.fill_axes_metadata! Method
fill_axes_metadata!(outcomes::YAXArray)::NothingFill outcomes axes metadata.
sourceADRIA.metrics.fill_metadata! Method
fill_metadata!(outcomes::YAXArray{T,N,A}, metric::Metric)::YAXArray{T,N,A} where {T,N,A}
fill_metadata!(outcomes::YAXArray{T,N,A}, metadata::Dict{Symbol,Any})::YAXArray{T,N,A} where {T,N,A}Fill outcomes YAXArray metadata (properties attribute).
Arguments
outcomes: YAXArray datacube of metric outcomes.metric: ADRIA.metrics.Metric object.metadata: Dict to be used to fill outcomes metrics metadata.
ADRIA.metrics.fog_ranks Method
fog_ranks(rs::ResultSet; kwargs...)Arguments
rs : ResultSet
kwargs : named dimensions to slice across
Returns
YAXArray[timesteps, sites, scenarios]
Example
ADRIA.metrics.fog_ranks(rs; timesteps=1:10, scenarios=3:5)ADRIA.metrics.loc_trajectory Method
loc_trajectory(metric, data::YAXArray{D,T,N,A})::YAXArray where {D,T,N,A}Alias for summarize(data, [:scenarios], metric). Collate trajectory for each location, applying metric across values for all scenarios.
Examples
using Statistics
rs = ADRIA.load_results("some results")
tac = ADRIA.metrics.total_absolute_cover(rs)
# Get median trajectory for each site
ADRIA.metrics.loc_trajectory(median, tac)
#75×216 YAXArray{Float64,2} with dimensions:
# Dim{:timesteps} Categorical{Any} Any[1, 2, …, 74, 75] Unordered,
# Dim{:locations} Categorical{Any} Any[1, 2, …, 215, 216] Unordered
#Total size: 126.56 KB
# Get upper 95% CI for each site
ADRIA.metrics.loc_trajectory(x -> quantile(x, 0.975), tac)
#75×216 YAXArray{Float64,2} with dimensions:
# Dim{:timesteps} Categorical{Any} Any[1, 2, …, 74, 75] Unordered,
# Dim{:locations} Categorical{Any} Any[1, 2, …, 215, 216] Unordered
#Total size: 126.56 KBArguments
metric : Any function (nominally from the Statistics package) to be applied to
datadata : Data set to apply metric to
Returns
2D array of
ADRIA.metrics.metadata Method
metadata(outcomes::YAXArray)::Dict{Symbol,Any}Helper function to extract metadata from YAXArrays.
sourceADRIA.metrics.metric_label Method
metric_label(m::Metric)::String
metric_label(f::Function, unit::String)Return name of metric in the format: "Title Case [Unit]", suitable for use as a label.
Example
m_label = metric_label(scenario_total_cover)
# "Scenario Total Cover [m²]"ADRIA.metrics.n_fog_locations Method
n_fog_locations(rs::ResultSet; kwargs...)::Matrix{Int64}Determine the number of locations fogged at each time step, for each scenario.
Returns
YAXArray[timesteps ⋅ scenarios] indicating the number of locations fogged at each time step.
sourceADRIA.metrics.n_seed_locations Method
n_seed_locations(rs::ResultSet; kwargs...)::Matrix{Int64}Determine the number of locations seeded at each time step, for each scenario.
Returns
YAXArray[timesteps ⋅ scenarios] indicating the number of locations seeded at each time step.
sourceADRIA.metrics.nds Function
nds(X::AbstractArray{<:Real}, dist::Int64=0)::Vector{Vector{<:Int}}Naive n-dimensional non-dominated sorting.
Adapted from: https://discourse.julialang.org/t/fast-optimized-non-dominated-sorting-algorithms/86793/7
Original function name is nds4()
Arguments
X : outcomes, where rows are scenarios and columns are metric results. dist : distance from front, where 0 is on the frontier.
Returns
Vector of Vectors with row indices for each dist from frontier, where 0 is on the frontier.
ADRIA.metrics.per_loc Method
per_loc(metric, data::YAXArray{D,T,N,A})::YAXArray where {D,T,N,A}Alias for summarize(data, [:scenarios, :timesteps], metric). Get metric results applied to the location-level at indicated time (or across timesteps).
Arguments
metric : Any function (nominally from the Statistics package) to be applied to
datadata : Data set to apply metric to
timesteps : timesteps to apply
metricacross
Returns
Named Vector of
ADRIA.metrics.scenario_outcomes Method
scenario_outcomes(rs::ResultSet, metrics::Vector{Metric})::YAXArrayGet outcomes for a given list of metrics and a result set.
Arguments
rs: ResultSetmetrics: Vector of scenario Metrics (the ones that start withscenario_)
Returns
YAXArray with (:timesteps, :scenarios, :outcomes)
Examples
metrics::Vector{ADRIA.metrics.Metric} = [
ADRIA.metrics.scenario_total_cover,
ADRIA.metrics.scenario_asv,
ADRIA.metrics.scenario_absolute_juveniles,
]
# 3-dimensional Array of outcomes
outcomes = ADRIA.metrics.scenario_outcomes(rs, metrics)ADRIA.metrics.scenario_trajectory Method
scenario_trajectory(data::AbstractArray; metric=mean)::YAXArray{<:Real}Produce scenario trajectories using the provided metric/aggregation function.
Arguments
data: Results to aggregatemetric: Function or Callable used to summarize data
Returns
Matrix[timesteps ⋅ scenarios]
sourceADRIA.metrics.seed_ranks Method
seed_ranks(rs::ResultSet; kwargs...)Arguments
rs : ResultSet
kwargs : named dimensions to slice across
Returns
YAXArray[timesteps, sites, scenarios]
Example
ADRIA.metrics.seed_ranks(rs; timesteps=1:10, scenarios=3:5)ADRIA.metrics.slice_results Method
slice_results(data::YAXArray; timesteps=(:), species=(:), locations=(:), scenarios=(:))Slice data as indicated. Dimensions not found in target data are ignored.
sourceADRIA.metrics.summarize Method
summarize(data::YAXArray{<:Real}, alongs_axis::Vector{Symbol}, metric::Function)::YAXArray{<:Real}
summarize(data::YAXArray{<:Real}, alongs_axis::Vector{Symbol}, metric::Function, timesteps::Union{UnitRange,Vector{Int64},BitVector})::YAXArray{<:Real}Apply summary metric along some axis of a data set across some or all timesteps.
Arguments
data: Data set to apply metric to.alongs_axis: which axis will be replaced with (😃 when slicing.metric: Any function (nominally from the Statistics package) to be applied todata.timesteps: timesteps to applymetricacross.
Returns
YAXArray with summary metric for the remaining axis.
sourceADRIA.metrics.summarize_absolute_shelter_volume Method
summarize_absolute_shelter_volume(sv::YAXArray; kwargs...)::Dict{Symbol,AbstractArray{<:Real}}
summarize_absolute_shelter_volume(rs::ResultSet, kwargs...)::Dict{Symbol,AbstractArray{<:Real}}Calculate summarized coral evenness.
sourceADRIA.metrics.summarize_coral_evenness Method
summarize_coral_evenness(raw::YAXArray; kwargs...)::Dict{Symbol,AbstractArray{<:Real}}
summarize_coral_evenness(rs::ResultSet, kwargs...)::Dict{Symbol,AbstractArray{<:Real}}Calculate summarized coral evenness.
sourceADRIA.metrics.summarize_raw Method
summarize_raw(data::YAXArray; kwargs...)::Dict{Symbol,AbstractArray{<:Real}}Summarize raw data, aggregating the specified dimensions (e.g., timesteps, scenarios, etc.) and collapsing given dims.
ADRIA.metrics.summarize_relative_cover Method
summarize_relative_cover(rc::YAXArray; kwargs...)::Dict{Symbol,AbstractArray{<:Real}}
summarize_relative_cover(rs::ResultSet, kwargs...)::Dict{Symbol,AbstractArray{<:Real}}Calculate summarized relative cover.
sourceADRIA.metrics.summarize_relative_shelter_volume Method
summarize_relative_shelter_volume(sv::YAXArray; kwargs...)::Dict{Symbol,AbstractArray{<:Real}}
summarize_relative_shelter_volume(rs::ResultSet, kwargs...)::Dict{Symbol,AbstractArray{<:Real}}Calculate summarized coral evenness.
sourceADRIA.metrics.summarize_total_cover Method
summarize_total_cover(raw::YAXArray, areas::AbstractArray{<:Real}; kwargs...)::Dict{Symbol,AbstractArray{<:Real}}
summarize_total_cover(rs::ResultSet; kwargs...)::Dict{Symbol,AbstractArray{<:Real}}Calculate summarized total absolute cover.
sourceADRIA.metrics.to_string Method
to_string(m::Metric)::StringGet name of metric as a string.
sourceADRIA.metrics.to_symbol Method
to_symbol(m::Metric)::StringGet name of metric as a symbol.
sourceADRIA.metrics.top_N_sites Method
top_N_sites(rs::ResultSet; N::Int64; metric::relative_cover)
top_N_sites(data::AbstractArray{Real}, N::Int64; stat=mean)Return the top N sites according to the provided metric (defaulting to mean of relative_cover).
Arguments
rs : ResultSet
N : Number of best performing sites to be selected
metric : Metric to use to order sites from best to worst, must take ResultSet as input
stat : Summary statistic to use for comparison (default: mean)
Returns
YAXArray[:scenarios, :locations], where locations indicates order of location ranking.
Example
ADRIA.metrics.top_N_sites(rs, 5)
ADRIA.metrics.top_N_sites(rs, 5; metric=ADRIA.metric.relative_cover)
ADRIA.metrics.top_N_sites(rs, 5; metric=ADRIA.metric.relative_cover, stat=median)ADRIA.metrics.top_n_seeded_sites Method
top_n_seeded_sites(rs::ResultSet, n::Int64; kwargs...)Get the top n seeded sites over time by their unique location id. Lower rank values are better (e.g., 1 = first choice)
Arguments
rs : ResultSet
n :
nlocations to retrievekwargs : dimensions to slice across
Returns
YAXArray[locations, [loc_id, loc_name, rank], scenarios]
sourceADRIA.metrics.trajectory_heatmap Method
trajectory_heatmap(data::YAXArray)::HeatMapEstimate heatmap of trajectories from a 2D dataset.
Arguments
- data : An N*D matrix where N is time steps and D is the scenario outcome for the given timestep in N
Returns
OnlineStats.HeatMap
sourceADRIA.metrics.trajectory_heatmap_data Method
trajectory_heatmap_data(data::YAXArray)::Tuple{Vector{Float64},Vector{Float64},Matrix{Int64}}Estimate heatmap of trajectories from a 2D dataset.
Arguments
- data : An N*D matrix where N is time steps and D is the scenario outcome for the given timestep in N
Returns
Tuple of xedges, yedges, and bi-dimensional histogram matrix
sourceBase.ndims Method
ndims(m::Metric)::Int64Infer the number of dimensions for a given outcome/metric.
sourceADRIA.metrics.Metric Method
(f::Metric)(raw, args...; kwargs...)
(f::Metric)(rs::ResultSet, args...; kwargs...)Makes Metric types callable with arbitrary arguments that are passed to associated function.
sourcePerformance indicators
ADRIA.performance.environmental_diversity Method
environmental_diversity(ms, inputs_i)Obtain an indication of environmental factor diversity for a scenario set. Higher values indicate a greater of mix of environmental conditions were experienced between scenarios.
This is referred to as
Arguments
ms : model spec
inputs_i : inputs used for scenarios of interest
ADRIA.performance.gmd Method
gmd(vals::AbstractVector{<:Real})::Float64
gmd(vals::AbstractMatrix{<:Real})Gini's Mean Difference.
The absolute mean of all pairwise distances between elements in a given set.
References
La Haye, R., & Zizler, P. (2019). The Gini mean difference and variance. METRON, 77(1), 43-52. https://doi.org/10.1007/s40300-019-00149-2
Yitzhaki, S. (2003). Gini's Mean difference: A superior measure of variability for non-normal distributions. Metron - International Journal of Statistics, LXI(2), 285-316. https://ideas.repec.org/a/mtn/ancoec/030208.html
Kashif, M., Aslam, M., Al-Marshadi, A. H., & Jun, C.-H. (2016). Capability Indices for Non-Normal Distribution Using Gini's Mean Difference as Measure of Variability. IEEE Access, 4, 7322-7330. https://doi.org/10.1109/ACCESS.2016.2620241
ADRIA.performance.intervention_diversity Method
intervention_diversity(ms, inputs_i)Obtain an indication of intervention diversity for a scenario. Higher values indicate a greater of mix of interventions options were applied.
This is referred to as
Arguments
ms : model spec
inputs_i : inputs used for scenarios of interest
ADRIA.performance.intervention_effort Method
intervention_effort(ms, inputs_i)Obtain an indication of intervention effort for each scenario and intervention type. This is referred to as
Arguments
ms : model spec
inputs_i : inputs used for scenarios of interest
Returns
Matrix of s * 8, where s is the number of scenarios and columns are: N_seed_TA, N_seed_CA, N_seed_CNA, N_seed_SM, N_seed_LM, fogging, SRM, seed_years, shade_years, fog_years
ADRIA.performance.normalize Method
normalize(vals::AbstractArray{<:Real})Normalize values using feature scaling such that values are bound between 0 and 1, where 1 is equivalent to the maximum value found.
sourceADRIA.performance.probability Method
probability(vals::AbstractArray{<:Real})Calculate probability of individual trajectories, given a scenario ensemble
ADRIA.performance.temporal_variability Method
temporal_variability(x::AbstractVector{<:Real})
temporal_variability(x::AbstractArray{<:Real, 2})
temporal_variability(x::AbstractArray{<:Real}, func_or_data...)The V meta-metric.
As a meta-metric, it can be applied to any combination of metrics (including itself), assuming
By default (detrend=true), variability is assessed on the first differences of detrend=false to instead assess variability on the raw values of
Examples
# Apply V to a time series
julia> temporal_variability(rand(50))
# Apply V to an ensemble of time series
julia> x = rand(50, 200)
julia> temporal_variability(x)
# Create and apply a modified V metric to an ensemble of time series.
# Where the argument is an array and not a function, the data is used directly
# and so it is assumed all matrices are of the same size and shape.
julia> temporal_variability(x, temporal_variabilty, temporal_variability(P(x)))
julia> temporal_variability(x, temporal_variabilty, P(x), D(x), E(x))Sensitivity
ADRIAanalysis.sensitivity._cramers_v Method
_cramers_v(col_vals, selection_mask) -> (statistic::Float64, effect_size::Float64)Cramer's V association strength between a nominal/unordered-categorical feature column col_vals and a binary selection_mask, via HypothesisTests.ChisqTest on the (n_levels x 2) contingency table of factor level vs. group membership.
V = sqrt(chi2 / (n * (min(n_rows, n_cols) - 1))), unsigned, in [0, 1]. n_cols is always 2 (the two selection_mask groups); n_rows is the number of unique values in col_vals. When col_vals has fewer than 2 unique values, min(n_rows, n_cols) - 1 would be zero (division by zero) – mirroring the zero-variance handling in rsa, this case emits a @warn and returns the sentinel (0.0, 0.0) instead.
ADRIAanalysis.sensitivity._rank_aligned_delta Method
_rank_aligned_delta(y_iv, y_cf_raw) -> (Vector{Float64}, Vector{Int})Sort both outcome vectors ascending and compute element-wise delta at matched rank positions. When lengths differ, the CF empirical quantile function is evaluated at the midpoint probability for each of the n_iv rank positions (p_r = (r - 0.5) / n_iv) to avoid boundary extrapolation.
Returns (y_delta, perm) where perm is the sort permutation applied to y_iv; apply fs_iv[perm, :] to keep the feature matrix aligned with y_delta.
ADRIAanalysis.sensitivity._stratified_rsa Method
_stratified_rsa(compute_si, fs, labels, strat_col, n_strata) -> DataFrameShared stratification/aggregation core for stratified_rsa. Bins fs into n_strata equal-frequency quantile groups on strat_col, drops DHW stat columns and zero-variance columns within each stratum, and calls compute_si(X_s, labels_s) per stratum – labels is either the scalar outcome vector y or a selection_mask, sliced to the stratum's rows. compute_si returns a per-stratum rsa result DataFrame, or nothing to skip the stratum (after emitting its own @warn).
ADRIAanalysis.sensitivity.convergence Method
convergence(X::DataFrame, y::YAXArray, target_factors::Vector{Symbol}; n_steps::Int64=10)::YAXArray
convergence(rs::ResultSet, X::DataFrame, y::YAXArray, components::Vector{String}; n_steps::Int64=10)::YAXArrayCalculates the PAWN sensitivity index for an increasing number of scenarios where the maximum is the total number of scenarios in scens. Number of scenario subsets determined by N_steps. Can be calculated for individual factors or aggregated over factors for specified model components.
Arguments
rs: Result set (only needed if aggregating over model components).X: Model inputsy: Model outputstarget_factors: Names of target factors represented by columns inX.components: Names of model components to aggregate over (e.g. [:Intervention, :Criteria]).n_steps: Number of steps to cut the total number of scenarios into.
Returns
YAXArray, of min, lower bound, mean, median, upper bound, max, std, and cv summary statistics for an increasing number of scenarios.
sourceADRIAanalysis.sensitivity.counterfactual_delta Method
counterfactual_delta(
rs_intervention::ResultSet,
rs_counterfactual::ResultSet,
metric_fn;
bootstrap_n::Int=0
) -> NamedTupleCompute per-scenario intervention lift (delta) and return the intervention feature matrix with DHW columns dropped, ready for rsa.
Both rs_intervention and rs_counterfactual are assumed to be independently Sobol'-sampled over the same parameter bounds.
Two estimators are available via delta_method:
:rank_aligned (default): Both outcome vectors are sorted ascending; the CF vector is interpolated to n_iv quantile positions if lengths differ. The lift for rank position r is:
y_delta[r] = y_iv^(r) - y_cf^(r)fs_intervention rows are permuted to the same sort order so that y_delta[r] and fs_intervention[r, :] always correspond to the same intervention scenario. RSA on this delta asks: "which factors characterise scenarios that beat the same-rank counterfactual outcome?"
:mean_difference: The lift for intervention scenario i is:
y_delta[i] = y_iv[i] - mean(y_cf)Note: because mean(y_cf) is a constant offset, RSA on this delta is mathematically equivalent to RSA on y_iv directly. fs_intervention row order is unchanged.
Arguments
rs_intervention: ResultSet from an intervention run.rs_counterfactual: ResultSet from a no-intervention (counterfactual) run.metric_fn: Functionrs -> AbstractVector{<:Real}mapping a ResultSet to a scalar outcome per scenario.delta_method::rank_aligned(default) or:mean_difference; see above.bootstrap_n: Number of bootstrap resamples for a 95% CI onmean(y_delta). 0 (default) skips bootstrapping.fs: Precomputedfeature_set(rs_intervention)to reuse, for callers that invokecounterfactual_deltarepeatedly against the samers_interventionwith differentmetric_fn/location restrictions (e.g. per-period or per-location-set repeats).feature_setis a pure function ofrs_interventionalone – independent ofmetric_fn– so recomputing it on every call (deployment-log summaries, DHW stats) is pure overhead once a caller needs more than one delta from the samers_intervention. Must have exactlylength(metric_fn( rs_intervention))rows, inrs_intervention's original scenario order (i.e.feature_set(rs_intervention)itself, unpermuted).nothing(default) computes it internally, as before.
Returns
NamedTuple with fields:
y_delta:Vector{Float64}– per-scenario lift (length = n intervention scenarios). With:rank_aligned, sorted ascending by outcome.fs_intervention:DataFrame–feature_set(rs_intervention)with DHW stat columns (:dhw_mean,:dhw_stdev,:dhw_complexity) removed. With:rank_aligned, rows are permuted to matchy_deltaorder.iv_perm:Vector{Int}– permutation applied to the intervention rows, i.e.fs_intervention/y_deltarowicorresponds to thei-th original intervention scenario (inmetric_fn(rs_intervention)order) at indexiv_perm[i]. Identity for:mean_difference. Callers holding other per-original-intervention-row arrays (e.g. aguided/unguidedmask) must index them withiv_permbefore lining them up againstfs_intervention/y_delta.bootstrap_ci:Union{Nothing, Tuple{Float64,Float64}}– bootstrapped 95% CI onmean(y_delta), ornothingifbootstrap_n == 0
Edge cases
If
all(y_delta .== 0), a@warnis emitted (ATE is zero; RSA will return sentinels).If either ResultSet has zero scenarios, throws
ArgumentError.
ADRIAanalysis.sensitivity.counterfactual_delta Method
counterfactual_delta(
rs::ResultSet,
cf_mask::AbstractVector{Bool},
metric_fn;
bootstrap_n::Int=0
) -> NamedTupleVariant of counterfactual_delta for result sets where intervention and counterfactual scenarios are stored together (e.g. rs.inputs.guided .== -1 marks the counterfactual group).
metric_fn is called once with the full rs; its output (one value per scenario) is then split by cf_mask. Intervention scenarios are all rows where cf_mask is false.
All other behaviour (delta_method, DHW column removal, optional bootstrap CI, the iv_perm return field) is identical to the two-ResultSet overload. Here iv_perm indexes into findall(.!cf_mask) order, i.e. the intervention rows of rs in their original order.
fs (optional): precomputed feature_set(rs) to reuse across repeated calls against the same rs with different metric_fn/location restrictions – see the two-ResultSet overload's docstring for the rationale. Must have length(cf_mask) rows in rs's original scenario order (i.e. feature_set(rs) itself, unpermuted and NOT pre-filtered to iv_mask). nothing (default) computes it internally, as before.
ADRIAanalysis.sensitivity.ks_statistic Method
ks_statistic(ks)Calculate the Kolmogorov-Smirnov test statistic.
sourceADRIAanalysis.sensitivity.pawn Method
pawn(rs::ResultSet, y::Union{NamedDimsArray,AbstractVector{<:Real}}; S::Int64=10)::NamedDimsArray
pawn(X::AbstractMatrix{<:Real}, y::AbstractVector{<:Real}, factor_names::Vector{String}; S::Int64=10)::NamedDimsArray
pawn(X::DataFrame, y::AbstractVector{<:Real}; S::Int64=10)::NamedDimsArray
pawn(X::NamedDimsArray, y::Union{NamedDimsArray,AbstractVector{<:Real}}; S::Int64=10)::NamedDimsArray
pawn(X::Union{DataFrame,AbstractMatrix{<:Real}}, y::AbstractMatrix{<:Real}; S::Int64=10)::NamedDimsArrayCalculates the PAWN sensitivity index.
The PAWN method (by Pianosi and Wagener) is a moment-independent approach to Global Sensitivity Analysis. Outputs are characterized by their Cumulative Distribution Function (CDF), quantifying the variation in the output distribution after conditioning an input over "slices" (
This implementation applies the Kolmogorov-Smirnov test as the distance measure and returns summary statistics (min, lower bound, mean, median, upper bound, max, std, and cv) over the slices.
Arguments
rs: ResultSetX: Model inputsy: Model outputsfactor_names: Names of each factor represented by columns inXS: Number of slides (default: 10)
Returns
YAXArray, of min, mean, lower bound, median, upper bound, max, std, and cv summary statistics.
Examples
dom = ADRIA.load_domain("example_domain", "<RCP>")
scens = ADRIA.sample(dom, 128)
rs = ADRIA.run_scenarios(dom, scens, "45")
# Get mean coral cover over time and locations
μ_tac = mean(ADRIA.metrics.scenario_total_cover(rs), dims=:timesteps)
ADRIAanalysis.sensitivity.pawn(rs, μ_tac)References
Pianosi, F., Wagener, T., 2018. Distribution-based sensitivity analysis from a generic input-output sample. Environmental Modelling & Software 108, 197-207. https://doi.org/10.1016/j.envsoft.2018.07.019
Baroni, G., Francke, T., 2020. GSA-cvd Combining variance- and distribution-based global sensitivity analysis https://github.com/baronig/GSA-cvd
Puy, A., Lo Piano, S., & Saltelli, A. 2020. A sensitivity analysis of the PAWN sensitivity index. Environmental Modelling & Software, 127, 104679. https://doi.org/10.1016/j.envsoft.2020.104679
https://github.com/SAFEtoolbox/Miscellaneous/blob/main/Review_of_Puy_2020.pdf
Extended help
Pianosi and Wagener have made public their review responding to a critique of their method by Puy et al., (2020). A key criticism by Puy et al. was that the PAWN method is sensitive to its tuning parameters and thus may produce biased results. The tuning parameters referred to are the number of samples (
Puy et al., found that the ratio of
ADRIAanalysis.sensitivity.quantile_strata_edges Method
quantile_strata_edges(vals::AbstractVector{<:Real}, n_strata::Int) -> Vector{Float64}Equal-frequency quantile bin edges for vals (length n_strata + 1), with the final edge nudged up by nextfloat so the maximum value falls inside the last bin: stratum s is edges[s] <= v < edges[s+1].
Used internally by stratified_rsa to bin strat_col; exposed so callers can derive a matching bin assignment for a different vector against the same edges (e.g. binning counterfactual scenarios' DHW values into the same strata as the intervention scenarios used to derive edges, as stratified_cf_mask does).
ADRIAanalysis.sensitivity.rsa Method
rsa(X::DataFrame, y::AbstractVector{<:Real};
top_proportion::Float64=0.9, method::Symbol=:auto) -> DataFrame
rsa(X::DataFrame, selection_mask::Union{BitVector,AbstractVector{Bool}};
method::Symbol=:auto) -> DataFrameRank-based Regional Sensitivity Analysis: score each input factor by how well it discriminates between high- and low-outcome scenario groups.
rsa is a rank-based, scenario-conditioned sensitivity method – it answers "which factors' distributions differ most between high- and low-outcome scenarios?" This complements PAWN/KS-based methods (which measure how the full output distribution shifts across the input space) rather than replacing them. Both are forms of sensitivity analysis; they answer related but distinct questions.
Test dispatch per column
Two tests are available:
Mann-Whitney U (
HypothesisTests.MannWhitneyUTest): appropriate for continuous, ordered-categorical, and ordered-discrete factors, where the two groups' ranks are meaningfully comparable.Cramer's V (
HypothesisTests.ChisqTeston a factor-level x group contingency table): appropriate for unordered/nominal categorical factors, where there is no meaningful notion of "rank".
With method=:auto (the default), each column of X is dispatched individually based on its DataFrames.colmetadata(X, col, "ptype", "continuous") value: columns tagged "unordered categorical" use Cramer's V; everything else ("continuous", "ordered categorical", "ordered discrete", "discrete", or no metadata at all) uses Mann-Whitney. Passing method=:mann_whitney or method=:cramers_v overrides this and forces every column through that single test regardless of its ptype tag.
Backwards-compatible fallback: if X has no colmetadata attached to any column (e.g. a plain, untagged DataFrame) and at least one column's eltype looks non-numeric (a heuristic proxy for "might actually be nominal but untagged"), a single @warn is emitted once before the per-feature loop, noting that no ptype metadata was found and Mann-Whitney is being applied indiscriminately – which is statistically invalid for nominal categorical factors. This is informational only: every untagged column still falls back to "continuous"/Mann-Whitney, matching pre-existing behaviour.
Primary dispatch: scalar outcomes
X: Feature matrix (DataFrame, columns = factors)y: Scalar outcome per scenario; scenarios above thetop_proportionquantile form the selected grouptop_proportion: Quantile threshold for the high-outcome group (default: 0.9)method::auto(default, per-column ptype dispatch),:mann_whitney, or:cramers_v(the latter two force uniform application to all columns)
Escape-hatch dispatch: pre-computed mask
X: Feature matrix (DataFrame, columns = factors)selection_mask: Boolean mask (true = selected/"high-outcome" group)method: Ranking method, as above
Returns
DataFrame sorted descending by prob_superiority:
feature (Symbol) : factor name
test (Symbol) :
:mann_whitneyor:cramers_v– which test produced this rowstatistic (Float64) : raw Mann-Whitney U, or the chi-squared statistic for Cramer's V rows
prob_superiority (Float64) : U / (n1 * n2), in [0, 1], for Mann-Whitney rows. Cramer's V has no equivalent "probability of superiority" concept (it is an unsigned association strength, not a rank comparison), so this is
NaNfor:cramers_vrows – following the same "not meaningful for this row" convention used for the zero-variance sentinel below, except NaN rather than 0.5 since there is no neutral value to report.effect_size (Float64) : 1 - 2*U / (n1 * n2), in
[-1, 1](signed), for Mann-Whitney rows; Cramer's V itself, in[0, 1](unsigned), for:cramers_vrows. These two are NOT on a comparable scale -- distinguish them via thetestcolumn, do not compareeffect_sizevalues across test types directly.
Because Mann-Whitney and Cramer's V effect sizes are not comparable, a result table containing BOTH test types does not produce a single meaningfully-ranked-together ordering: sort!(result, :prob_superiority; rev=true) will place all :cramers_v rows (prob_superiority = NaN) according to Julia's NaN sort ordering, not by association strength. Callers wanting a proper within-statistic ranking should filter by test first (e.g. filter(:test => ==(:mann_whitney), result)).
HypothesisTests.MannWhitneyUTest applies a normal approximation with tie correction. A @warn is emitted when more than 20% of values in a feature column are tied, as the effect_size formula becomes less reliable in that case.
Known confound: for factors like mcda_method (sentinel-zeroed/inapplicable when guided <= 0), Cramer's V will partly re-detect "is guided active at all", a signal guided's own Mann-Whitney effect size already captures separately. This is a known, expected confound – it is documented here rather than engineered around.
ADRIAanalysis.sensitivity.stratified_cf_mask Method
stratified_cf_mask(y_iv::AbstractVector{<:Real}, dhw_iv::AbstractVector{<:Real},
y_cf::AbstractVector{<:Real}, dhw_cf::AbstractVector{<:Real};
n_strata::Int=4, quantile_level::Float64=0.8,
min_stratum_n::Int=10) -> BitVectorBehavioural mask for intervention scenarios, with the "behavioural" bar set locally per DHW stratum: scenario i is behavioural iff y_iv[i] beats the quantile_level quantile of counterfactual outcomes (y_cf) drawn from the SAME DHW stratum as scenario i.
Bin edges are the equal-frequency quantile edges of dhw_iv (see quantile_strata_edges); dhw_cf is binned into those same edges so each stratum's threshold is computed from counterfactual scenarios under comparable climate conditions.
This is deliberately local rather than global: a single global quantile(y_cf, quantile_level) threshold, especially at a high quantile_level, is disproportionately clearable only by scenarios drawn under mild DHW – passed to stratified_rsa, that collapses the "which factors matter within this DHW band" question back into "which DHW band is mild", which stratification exists to avoid. Since DHW is fixed within a stratum here, "beat the local top 1 - quantile_level of counterfactual outcomes" isolates intervention-parameter effects from climate severity instead.
Strata with fewer than min_stratum_n counterfactual scenarios fall back to the GLOBAL quantile_level quantile of y_cf, with a @warn.
ADRIAanalysis.sensitivity.stratified_rsa Method
stratified_rsa(fs::DataFrame, y::AbstractVector{<:Real};
strat_col::Symbol=:dhw_mean,
n_strata::Int=4,
top_proportion::Float64=0.9) -> DataFrame
stratified_rsa(fs::DataFrame, selection_mask::Union{BitVector,AbstractVector{Bool}};
strat_col::Symbol=:dhw_mean,
n_strata::Int=4) -> DataFrameRun rsa independently within each DHW quantile stratum and return a long-format DataFrame summarising factor importance across strata.
Scenarios are binned into n_strata equal-frequency quantile groups on strat_col (default :dhw_mean). DHW stat columns (dhw_mean, dhw_stdev, dhw_complexity) are dropped from the feature matrix within each stratum before calling rsa, so they do not confound the within-stratum ranking.
Primary dispatch: scalar outcomes
fs: Feature matrix as returned byfeature_set(rs), which must containstrat_colas a column.y: Scalar outcome per scenario (same row order asfs).strat_col: Column offsused to form strata (default:dhw_mean).n_strata: Number of equal-frequency quantile bins (default 4).top_proportion: Passed through torsa; quantile threshold for the high-outcome group within each stratum (default 0.9).
Escape-hatch dispatch: pre-computed mask
fs: Feature matrix, as above.selection_mask: Boolean mask (true = selected/"behavioural" group), same row order asfs. Sliced per stratum and passed straight torsa's mask dispatch – the caller decides how the behavioural split is defined (e.g. against a counterfactual threshold) rather thanstratified_rsare-deriving a per-stratum quantile fromyitself.strat_col,n_strata: As above.
Returns
Long-format DataFrame with columns:
feature(Symbol) : factor namestratum(Int) : stratum index 1..n_strata (low->high DHW)prob_superiority(Float64) : Mann-Whitney P(X1 > X2) for this factor in this stratumeffect_size(Float64) : 1 - 2U/(n1*n2)mean_importance(Float64) : mean of abs(prob_superiority - 0.5) across all strata (same value repeated per row). Measures average deviation from neutrality; a factor with reversed importance across strata (e.g. [0.9, 0.1]) scores the same as a consistently important one ([0.9, 0.9]), both higher than a neutral factor ([0.5, 0.5]).
Strata that contain fewer than 10 scenarios are skipped with a @warn. For the scalar-outcome dispatch, strata where all outcome values are identical are also skipped; for the mask dispatch, strata where the sliced mask is all-true or all-false are skipped instead. Skipped strata are absent from the returned DataFrame.
ADRIAanalysis.sensitivity.tsa Method
tsa(X::DataFrame, y::AbstractMatrix)::YAXArrayPerform Temporal (or time-varying) Sensitivity Analysis using the PAWN sensitivity index.
The sensitivity index value for time
Examples
rs = ADRIA.load_results("a ResultSet of interest")
# Get scenario outcomes over time (shape: `time × scenarios`)
y_tac = ADRIA.metrics.scenario_total_cover(rs)
# Calculate sensitivity of outcome to factors for each time step
ADRIAanalysis.sensitivity.tsa(rs.inputs, y_tac)Arguments
X: Scenario specificationy: scenario outcomes over time
Returns
YAXArray, of shape × 6 × , where
is the number of dimensions/factors
6 corresponds to the min, mean, median, max, std, and cv of the PAWN indices
is the number of time steps
General API
ADRIA.bin_edges Method
bin_edges()Helper function defining coral colony diameter bin edges. The values are converted from cm to the desired unit. The default target unit is cm.
ADRIA.coral_spec Method
coral_spec()::NamedTupleReturn the coral parameter specification for ADRIA. Includes "vital" bio/ecological parameters for each coral taxa, functional group, and size class.
Results are cached: the value is computed once per session and persisted to disk at ~/.julia/cache/ADRIA/coral_spec-julia<X.Y>-adria<V>.cache. The cache filename encodes the Julia minor version and ADRIA version, so stale files from other versions are never loaded. Within a file, the cache is also keyed to a hash of Corals.jl, so it is invalidated automatically whenever the source file changes.
Returns
A NamedTuple with fields:
taxa_names: names of functional groupsparam_names: names of perturbable parametersparams:DataFrameof parameter values for each taxa/size-class combination
Developer notes
To force recomputation within a live session (e.g. after reloading with Revise):
ADRIA.invalidate_coral_spec_cache!()If struct fields changed, also call ADRIA.create_coral_struct() afterwards.
ADRIA.create_coral_instance Function
create_coral_instance(bounds=(0.9, 1.1); overrides=Dict())Construct a Coral instance with calibrated field values without redefining the struct. Use this instead of create_coral_struct when only an instance (not a struct redefinition) is needed.
ADRIA.create_coral_struct Function
create_coral_struct(bounds=(0.9, 1.1))Generates Coral struct using the default parameter spec.
Example
# Define coral struct with auto-generated parameter ranges
# (default in ADRIA is ± 10%, triangular distribution with peak at 0.5)
create_coral_struct()
coral = Coral()
# Recreate coral spec ± 50% from nominal values
create_coral_struct((0.5, 1.5))
coral = Coral()ADRIA.env_stats Method
env_stats(rs::ResultSet, s_name::String, rcp::String)
env_stats(rs::ResultSet, s_name::String, rcp::String, scenario::Int)
env_stats(rs::ResultSet, s_name::String, stat::String, rcp::String, scenario::Int)Extract statistics for a given environmental layer ("DHW" or "wave")
sourceADRIA.loc_area Method
loc_area(rs::ResultSet)::Vector{Float64}Extract vector of a location's total area in its areal unit (m², km², etc).
sourceADRIA.loc_area Method
loc_area(domain::Domain)::Vector{Float64}Get location area for the given domain.
sourceADRIA.loc_coral_cover Method
loc_coral_cover(C_cover_t::Array{Float64,3})::Vector{Float64}Sum coral cover across all functional groups and size classes of a single timestep for each location.
sourceADRIA.loc_k_area Method
loc_k_area(rs::ResultSet)::Vector{Float64}Extract vector of a location's coral carrying capacity in terms of absolute area.
sourceADRIA.loc_k_area Method
loc_k_area(domain::Domain)::Vector{Float64}Get maximum coral cover area for the given domain in absolute area.
sourceADRIA.loc_recruits_cover Method
loc_recruits_cover(recruits::Matrix{Float64})::Vector{Float64}Absolute cover of recruits on each location.
sourceADRIA.run_scenario Method
run_scenario(domain::Domain, idx::Int64, scenario::Union{AbstractVector,DataFrameRow}, functional_groups::Vector{Vector{FunctionalGroup}}, data_store::NamedTuple)::Nothing
run_scenario(domain::Domain, scenario::Union{AbstractVector,DataFrameRow})::NamedTuple
run_scenario(domain::Domain, scenario::Union{AbstractVector,DataFrameRow}, RCP::String)::NamedTupleRun individual scenarios for a given domain, saving results to a Zarr data store. Results are stored in Zarr format at a pre-configured location. Sets up a new cache if not provided.
Arguments
domain: Simulation domain (may be modified viaswitch_RCPs!).idx: Scenario index, to store results intodata_store.scenario: Parameter row describing the scenario.functional_groups: Preallocated functional group buffers.data_store: Pre-opened store with arrays to write results into.
Returns
Nothing
sourceADRIA.select Method
select(r::ResultSet, op::String)Hacky scenario filtering - to be replaced with more robust approach.
Only supports filtering by single attribute. Should be expanded to support filtering metric results too.
Examples
select(result, "guided .> 0.0")
# Above expands to:
# result.inputs.guided .> 0.0ADRIA.timesteps Method
timesteps(rs::ResultSet)Retrieve the time steps represented in the result set.
Arguments
rs: ResultSet
ADRIA.timesteps Method
timesteps(outcomes::YAXArray)::Vector{Int64}Extract time step labels from a YAXArray. Returns an empty Vector{Int64} if the array has no :timesteps dimension.
ADRIA.ADRIADomain Type
ADRIADomain{Σ,M,I,D,X,Y,Z}Core ADRIA domain. Represents study area.
sourceADRIA.Domain Method
Domain(name::String, dpkg_path::String, rcp::String, timeframe::Vector, location_data_fn::String, location_id_col::String, cluster_id_col::String, k_area_col::String, area_col::String, init_coral_fn::String, conn_path::String, dhw_fn::String, wave_fn::String, cyclone_mortality_fn::String; calib_params_fn::String="")::ADRIADomainConvenience constructor for Domain.
Arguments
name: Name of domaindpkg_path: location of data packagercp: RCP scenario representedtimeframe: Time steps representedlocation_data_fn: File name of spatial data usedlocation_id_col: Column holding name of reef the location is associated with (non-unique)cluster_id_col: Column holding unique cluster names/idsk_area_col: Column holding habitable area proportionarea_col: Column holding location areainit_coral_fn: Name of file holding initial coral cover valuesconn_path: Path to directory holding connectivity datadhw_fn: Filename of DHW data cube in usewave_fn: Filename of wave data cubecyclone_mortality_fn: Filename of cyclone mortality data cubecalib_params_fn: path to a CoralBlox calibration NetCDF. If empty or missing, ADRIA
default coral and growth acceleration parameters are used.
sourceADRIA.Domain Method
Barrier function to create Domain struct without specifying Intervention, Criteria, Coral or SimConstant parameters, which are constructed internally.
Coral and growth acceleration parameters are taken from calib_params_fn when given, and default to ADRIA values otherwise.
ADRIA.SimConstants Type
SimConstantsStruct of simulation constants for ADRIA
References
Lough, J. M., Anderson, K. D., & Hughes, T. P. (2018). Increasing thermal stress for tropical coral reefs: 1871-2017. Scientific Reports, 8(1), 6079. https://doi.org/10.1038/s41598-018-24530-9
Hughes, T. P., Kerry, J. T., Baird, A. H., Connolly, S. R., Dietzel, A., Eakin, C. M., Heron, S. F., Hoey, A. S., Hoogenboom, M. O., Liu, G., McWilliam, M. J., Pears, R. J., Pratchett, M. S., Skirving, W. J., Stella, J. S., & Torda, G. (2018). Global warming transforms coral reef assemblages. Nature, 556(7702), 492-496. https://doi.org/10.1038/s41586-018-0041-2
Bozec, Y.-M., Rowell, D., Harrison, L., Gaskell, J., Hock, K., Callaghan, D., Gorton, R., Kovacs, E. M., Lyons, M., Mumby, P., & Roelfsema, C. (2021). Baseline mapping to support reef restoration and resilience-based management in the Whitsundays. https://doi.org/10.13140/RG.2.2.26976.20482
Bozec, Y.-M., Hock, K., Mason, R. A. B., Baird, M. E., Castro-Sanguino, C., Condie, S. A., Puotinen, M., Thompson, A., & Mumby, P. J. (2022). Cumulative impacts across Australia's Great Barrier Reef: A mechanistic evaluation. Ecological Monographs, 92(1), e01494. https://doi.org/10.1002/ecm.1494