Skip to contents

Run a small simulation-based tuning grid for one information-criterion workflow at a time. This helper evaluates combinations of shift_acceptance_threshold and min_descendant_tips under a fixed IC value by combining:

  • a null false-positive study,

  • a proportional shift-recovery study, and

  • a non-proportional correlation robustness study.

The goal is to support practical tuning workflows such as "find the best search settings under GIC" or "find the best search settings under BIC" without treating IC as just another free parameter in one large optimization.

Usage

runSearchTuningGrid(
  template,
  IC = c("GIC", "BIC"),
  shift_acceptance_thresholds,
  min_descendant_tips_values,
  tree_tip_count = NULL,
  null_replicates = 50,
  recovery_replicates = 50,
  null_simulation_options = list(),
  proportional_simulation_options,
  correlation_simulation_options = NULL,
  base_search_options = list(),
  fuzzy_distance = 2,
  weighted = TRUE,
  num_cores = 1,
  seed = NULL,
  store_studies = FALSE
)

Arguments

template

A bifrost_simulation_template returned by createSimulationTemplate().

IC

Character scalar, either "GIC" or "BIC". The tuning grid is run for this IC family only.

shift_acceptance_thresholds

Finite, non-negative numeric vector of candidate shift_acceptance_threshold values to evaluate.

min_descendant_tips_values

Integer vector of candidate min_descendant_tips values to evaluate.

tree_tip_count

Optional integer tip count passed to the simulation study wrappers. If NULL, each study uses the full empirical tree.

null_replicates

Integer number of null replicates run for each grid row.

recovery_replicates

Integer number of shifted replicates run for each grid row in both the proportional and correlation scenarios.

null_simulation_options

Named list forwarded to runFalsePositiveSimulationStudy(). The "original" manuscript generator is used when simulation_generator is omitted. Its simulation_generator entry must contain exactly one supported string.

proportional_simulation_options

Named list forwarded to runShiftRecoverySimulationStudy() for the proportional generating-model scenario. Must include num_shifts, min_shift_tips, and max_shift_tips. Its simulation_generator entry must contain exactly one supported string.

correlation_simulation_options

Optional named list forwarded to runShiftRecoverySimulationStudy() for the non-proportional robustness scenario. The argument name is retained for compatibility with the scale_mode = "correlation" label. Under the default "original" generator it controls the published transform; under simulation_generator = "empirical" it controls the integration-rate trade-off. Its simulation_generator entry must contain exactly one supported string. If NULL, the proportional options are reused and only scale_mode is changed to "correlation".

base_search_options

Named list of search options shared across all grid rows. The tuning helper overwrites IC, shift_acceptance_threshold, and min_descendant_tips for each row. Simulation-grid searches are intentionally intercept-only, so formula should remain "trait_data ~ 1" (or an equivalent intercept-only response formula). If omitted, the helper inherits template$search_formula.

fuzzy_distance

Integer node distance passed to evaluateShiftRecovery() inside the shifted-study wrappers.

weighted

Logical; if TRUE, request weighted recovery summaries from runShiftRecoverySimulationStudy() and include weighted fuzzy F1 columns in the output table.

num_cores

Integer number of workers used across grid settings. When num_cores > 1, runSearchTuningGrid() parallelizes over settings and forces the dependent study wrappers and search calls to run serially within each setting.

seed

Optional integer seed used to derive deterministic per-study seeds across the entire grid. When supplied, the wrapper restores the caller's previous RNG state before returning.

store_studies

Logical; if TRUE, retain the raw study objects for every grid row and scenario. If FALSE, return only the summary table and metadata.

Value

A list of class bifrost_search_tuning_grid with components:

IC

The fixed IC family used across the grid.

grid

The evaluated combinations of thresholds and minimum clade sizes.

summary_table

A data frame with one row per setting, deterministic per-study seed columns, and summary metrics from the null, proportional, and correlation-scenario studies.

simulation_generators

A named character vector recording the null, proportional, and non-proportional simulation generators.

studies

Either NULL or a list of raw study objects for each grid row and scenario, depending on store_studies.

base_search_options

The shared search options used before the tuned grid parameters were injected.

Details

This function is intentionally conservative in scope. It does not try to optimize over IC; instead, it assumes that GIC and BIC should be tuned as separate workflows. In typical use, you call it twice, once with IC = "GIC" and once with IC = "BIC", then select one recommended setting from each grid with selectTunedSearchParameters().

The template may come from a richer global calibration model, but each grid row is still evaluated with an intercept-only shift search on the simulated response block. This follows the residual-calibration workflow used by the simulation-study wrappers. Covariates in the calibration model influence the fitted means and residual covariance used for simulation, but they are not re-fit inside each grid replicate.

The returned summary_table contains one row per grid combination. Null summaries emphasize false-positive behavior, while proportional and correlation-scenario summaries emphasize recovery, including fuzzy balanced accuracy. The corresponding output columns retain their correlation_ prefixes for backward compatibility. When seed is supplied, the null_seed, proportional_seed, and correlation_seed columns record the deterministic per-study seeds used for each setting; otherwise those columns are NA. Candidate-set availability among completed searches is tracked via evaluable fractions so that overly strict min_descendant_tips settings can be screened out before choosing a final workflow. Completion and failure rates are reported separately and failed searches are excluded from scientific means and proportions.

Parallelism is owned by the top-level function that the user calls. In this helper, num_cores is interpreted at the setting level, so dependent study wrappers are always called with num_cores = 1 and their embedded search calls are forced to num_cores = 1 as well. This avoids nested parallelism while keeping the user-facing API simple.

Examples

if (FALSE) { # \dontrun{
set.seed(1)
tr <- ape::rtree(40)
X <- matrix(rnorm(40 * 3), ncol = 3)
rownames(X) <- tr$tip.label
tmpl <- createSimulationTemplate(tr, X, formula = "trait_data ~ 1", method = "LL")

gic_grid <- runSearchTuningGrid(
  template = tmpl,
  IC = "GIC",
  shift_acceptance_thresholds = c(2, 10),
  min_descendant_tips_values = c(5, 10),
  null_replicates = 10,
  recovery_replicates = 10,
  proportional_simulation_options = list(
    num_shifts = 2,
    min_shift_tips = 5,
    max_shift_tips = 10
  ),
  base_search_options = list(
    formula = "trait_data ~ 1",
    method = "LL"
  ),
  num_cores = 1,
  seed = 1
)

head(gic_grid$summary_table)
} # }