Captures the preparation logic common to every GLOW SNV-set scan module (gene, sliding-window, or coding): create the output directory tree, validate that every per-chromosome GDS file is present, load the prepared phenotype/covariate object and align its samples to GDS sample order, fit the GLOWr null model, load the PI models and resolve the PI feature set, dispatch the B source (b_func xor b_model_path, with a probe/load sanity check), compute input checksums, and assemble the base fields of the resolved-config snapshot.

prepare_scan_run(
  config,
  output_dir,
  chroms = 1:22,
  make_dirs = character(0),
  config_path = NULL,
  verbose = 0
)

Arguments

config

An environment or named list of resolved configuration values (typically the environment populated by source(config_path, local = TRUE)). Required fields: gds_dir, gds_pattern, pheno_path, pi_model_dir, filter_spec. Optional: pi_features (NULL -> GLOWr defaults), b_func, b_model_path (exactly one of these two), and symlinked_shared_root (where a new output_dir physically lives — see Born-shared below: a path symlinks outputs into it; NULL keeps them local; absent uses the default shared root). The resolved value is recorded in the snapshot.

output_dir

Character. Run output directory; shared/ and any make_dirs are created beneath it.

chroms

Integer vector of chromosomes whose GDS files must be present (default 1:22). The first element's GDS is opened for sample alignment.

make_dirs

Character vector of additional directory names (relative to output_dir) to create alongside shared/. Default character(0) (only shared/).

config_path

Character or NULL. Path to the sourced config file, stored in base_snapshot$config_path and read line-by-line into base_snapshot$config_source. If NULL both are NULL.

verbose

Integer. 0 = silent (default); >= 1 prints progress, matching the calling scripts' cat() chatter.

Value

A named list (the "bundle"):

null_model

Fitted GLOWr::fit_null_model object (GDS order).

pi_models

Loaded PI models (GLOWr::load_PI_models).

pi_features

Resolved character vector of PI feature names.

b_func

The closed-form B function, or NULL.

b_model

The loaded trained B model, or NULL.

filter_spec

The config's filter_spec (echoed back).

sample_ids

Aligned sample IDs in GDS order.

checksums

Named list of MD5 sums for every input file.

base_snapshot

Named list of the base config_used fields shared by all modules (paths, resolved filter/feature settings, trait, provenance git_sha/session_info/prepared_at). The caller merges these with its module-specific snapshot fields.

gds_files

Named (by chr) character vector of per-chr GDS paths.

Details

What it does (the spine). The steps below capture the preparation shared by every scan type, so a run's prepared outputs are stable and reproducible:

  1. Create <output_dir>/shared (always) plus any directories named in make_dirs.

  2. Validate gds_dir, pheno_path, pi_model_dir exist; build per-chromosome GDS paths for chroms from gds_pattern and error if any are missing.

  3. Dispatch the B source: exactly one of b_func (a closed-form function, probed at MAF 0.1 for a finite scalar) and b_model_path (a trained model, loaded via GLOWr::load_B_model) must be set.

  4. Read pheno_path; intersect its sample_id with the first requested chromosome's GDS sample set; align Y/X to GDS order.

  5. Fit the null model with GLOWr::fit_null_model (trait from prep$trait, default "binary").

  6. Load the PI models (GLOWr::load_PI_models); resolve PI features (config pi_features, else GLOWr:::.default_PI_features()).

  7. Compute MD5 checksums of every input file (passive audit trail).

What it does NOT do. Type-specific preparation work stays in the calling script and runs after prepare_scan_run: STAAR null models, the custom gene-list resolver, the per-chromosome annotation-median cache + chromosome spans, the genome chunk table, the essentialdb annotation catalog, and GC calibration. Those are folded into each module's own snapshot and artifact writes so each scan type's outputs stay reproducible.

Side effects (writes). Writes <output_dir>/shared/01-null_model.rds and <output_dir>/shared/01-input_checksums.rds. The caller still writes 01-config_used.rds (base fields from base_snapshot + its extras) and any module-specific artifacts. Born-shared: when run inside a repo that ships tools/shared-storage/scaffold_shared_output.sh, a not-yet-existing output_dir is first created as a symlink into the lab-shared storage (so the run's outputs live off /home and are registered for clone reconstruction); this is a portable no-op otherwise (plain local dir), and the output content is unchanged either way. Controlled per run by the config field symlinked_shared_root: a directory path symlinks output_dir into <path>/<repo-relative-leaf>; NULL keeps it a plain local dir; an absent field uses the shared-storage tooling's default root (tools/shared-storage/shared-root.conf). Set it in the run's config.R / base-config.

Complexity. Dominated by fit_null_model (one GLM fit on the aligned cohort) and one GDS open per requested chromosome for presence/sample checks. Memory is O(n samples \(\times\) covariates) for the design matrix.

Examples

if (FALSE) { # \dontrun{
env <- new.env(); source("runs/myrun/config.R", local = env)
bundle <- prepare_scan_run(env, output_dir = "runs/myrun/outputs",
                           chroms = 22L, verbose = 1)
str(bundle$base_snapshot)
} # }