Coverage Normalization¶
Normalizes mosdepth coverage in two steps: within-individual (divide by sample mean) and across-individual (z-score transformation). High-variance regions are then selected to reduce noise before neighbor computation.
- grid.utils.normalize_mosdepth.build_depth_matrix(regions_to_extract)¶
Build depth matrix from extracted regions.
- Parameters:
regions_to_extract (dict[str, list[tuple[int, int, float]]]) – Dictionary of sample IDs to region lists
- Returns:
{(start,end): depth}}
- Return type:
Dictionary mapping {sample
- grid.utils.normalize_mosdepth.build_matrix_from_regions(regions_to_extract, individuals_order=None)¶
Build numpy matrix from regions_to_extract.
- Parameters:
regions_to_extract – dict of {individual_id: [(start,end,depth),…]}
individuals_order – optional list of individual IDs to order rows
- Returns:
list of individual IDs in order regions_list: list of (start,end) tuples in order mat: numpy array of shape (n_individuals, n_regions) with depths
- Return type:
individuals_order
- grid.utils.normalize_mosdepth.compute_population_mean_depths(individuals, mosdepth_dir, chromosome, start, end, excluded, threads=1, console=None)¶
Compute the population mean depth for every region across all individuals.
This mirrors the C++ first pass (batches 0–9) that computes mean_depths[] and uses it as the depth filter threshold — so the region mask is universal (same regions included/excluded for every sample) rather than per-sample.
- Parameters:
individuals (dict[str, Path]) – {sample_id: bed_gz_path}
mosdepth_dir (str) – directory with mosdepth output (passed through to reader)
chromosome (str) – target chromosome (or None for all)
start/end – target region bounds (or None for whole chromosome)
excluded (dict[str, set[int]]) – repeat-mask kb bins {chrom: set(kb)}
threads (int) – worker threads for parallel reading
console – Rich console for logging
start (int)
end (int)
- Returns:
population_mean_depth}
- Return type:
{(region_start, region_end)
- grid.utils.normalize_mosdepth.filter_empty_samples(regions_to_extract, console=None)¶
Remove samples that have zero regions.
- Parameters:
regions_to_extract (dict[str, list[tuple[int, int, float]]]) – dict of {sample_id: [(start, end, depth), …]}
console – optional Rich console for logging
- Returns:
Filtered dictionary with only samples that have ≥1 region
- grid.utils.normalize_mosdepth.find_bed_gz_for_individual(individual_id, mosdepth_dir)¶
Find the .regions.bed.gz file for a given individual in the mosdepth directory.
- Parameters:
individual_id (str) – Sample ID to find
mosdepth_dir (str) – Directory containing mosdepth output files
- Returns:
Path to the individual’s .regions.bed.gz file, or Path to non-existent file if not found
- Return type:
Path
- grid.utils.normalize_mosdepth.load_repeat_mask(repeat_bed)¶
Load repeat regions into {chrom: set(kb_bins)}.
- Parameters:
repeat_bed (str) – Path to repeat mask BED file
- Returns:
Dictionary mapping chromosomes to sets of excluded kb bins
- Return type:
dict[str, set[int]]
- grid.utils.normalize_mosdepth.map_mosdepth_files_to_samples(mosdepth_dir, samples)¶
Map sample IDs to their mosdepth.global.dist files.
- Parameters:
mosdepth_dir (str) – Directory containing mosdepth output files
samples (list[str]) – List of sample IDs
- Returns:
Dictionary mapping sample IDs to their global.dist file paths
- Return type:
dict[str, Path]
- grid.utils.normalize_mosdepth.norm_chrom(chrom)¶
Normalise a chromosome name to ‘chrN’ form. ‘6’ -> ‘chr6’, ‘chr6’ -> ‘chr6’, ‘chrX’ -> ‘chrX’
- Parameters:
chrom (str)
- Return type:
str
- grid.utils.normalize_mosdepth.normalize_matrix(mat)¶
Normalize the depth matrix to match C++ normalize_mosdepth_inflow logic.
- Steps:
Row-wise (within-individual): divide each row by its mean depth.
Column-wise (across-individual): for each region compute mu and sigma2, then transform x -> (x - mu) / sqrt(mu).
Compute variance ratios (100 * sigma2 / mu) for every region.
Median-based rescaling: multiply all values by 1/sqrt(median_ratio/100) so the output approximates true z-scores (matches C++ scale factor).
- Parameters:
mat – numpy array shape (n_individuals, n_regions) with raw depths.
- Returns:
numpy array same shape, rescaled z-scores. variance_ratios: dict {region_index: 100*sigma2/mu} for non-NaN regions.
- Return type:
normalized_mat
- grid.utils.normalize_mosdepth.normalize_mosdepth(config, console)¶
Normalizes mosdepth coverage for all samples in the config file.
- Parameters:
config (dict) – The configuration data loaded from the config file.
console (Console) – The Rich console object for logging.
- grid.utils.normalize_mosdepth.process_one_individual(individual_id, mosdepth_dir, chromosome, start, end, valid_regions, excluded)¶
This runs in its own process. Returns (individual_id, [(start,end,depth),…]) args_tuple contains:
individual_id, mosdepth_dir, chromosome, start, end, min_depth, max_depth, excluded
- grid.utils.normalize_mosdepth.select_high_variance_regions(variance_ratios, top_frac=0.9)¶
Select top fraction of regions by variance ratio.
- Parameters:
variance_ratios (dict[int, float]) – {region_index: variance_ratio}
top_frac (float) – fraction of top regions to retain
- Returns:
List of selected region indices
- Return type:
list[int]
- grid.utils.normalize_mosdepth.write_normalized_output(mat, individuals_order, selected_indices, output_file, col_means, col_vars, individual_raw_means, ratio_mult=100.0)¶
Write normalised matrix in the C++-compatible format.
File layout¶
Line 0 : N <tab> Rwant <tab> mu_1 <tab> mu_2 … Line 1 : N <tab> Rwant <tab> varRatio_1 <tab> varRatio_2 … Line 2+ : ID <tab> indiv_scale <tab> z_1 <tab> z_2 …
- param mat:
normalised + rescaled matrix (n_individuals × n_regions).
- param individuals_order:
list of sample IDs.
- param regions_list:
list of (start, end) tuples for all regions.
- param selected_indices:
indices of high-variance regions to keep.
- param output_file:
Path for the output .tsv.gz file.
- param col_means:
per-region means (length = n_regions).
- param col_vars:
per-region variances ddof=1 (length = n_regions).
- param individual_raw_means:
per-sample mean depth before any normalisation (used to write the scale column; matches C++ 0.01f*scales[n] where scales[n] was in units of 0.01x, so the written value is in 1x units).
- param ratio_mult:
multiplier used for variance ratios (default 100).
- Parameters:
mat (ndarray)
individuals_order (list)
selected_indices (list)
output_file (Path)
col_means (ndarray)
col_vars (ndarray)
individual_raw_means (ndarray)
ratio_mult (float)