feat: per-sample reference support via manifest ref/ref_name columns - #68
feat: per-sample reference support via manifest ref/ref_name columns#68mrvollger wants to merge 4 commits into
Conversation
|
Update per review: chromosome lists now preserve BAM header order instead of sorting lexicographically — header order is the data's sort order. |
snakefmt's shell formatting (shfmt) is active in the current pixi env and reformats every shell block. Two pre-existing '((cat $(...)' subshells are disambiguated to '( (cat ...' because shfmt correctly rejects the former as arithmetic. No functional changes. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
d543389 to
22c51a9
Compare
|
Rebased into two commits for reviewability: |
|
Ran a multi-agent code review over the feature commit (17 agents, 4 lenses, every finding adversarially verified — 13 confirmed, 0 refuted). All fixed in Validation robustness — numeric or NA-like sample names ( levio (chain mode) — the index rule wrote to a hardcoded shared path instead of its declared per-sample output (pre-existing), and the lift rules were un-instantiable because their outputs lacked genome_file — back to an Test hardening — rendered-shell excludes checks are now sample-attributed (a leak of hg38 paths into the non-hg38 sample now fails, as does exclude duplication from the list-mutation class of bug); a new Full dry-run matrix (now 26 checks) and the four-sample multi assertions pass locally; CI rerunning. |
Stacked pull requests have a non-main base and previously got no checks. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Nothing consumes the leviosam2 outputs, chain mode has been broken since the fire rule stopped producing a bam (its input referenced a bam output that no longer exists), and the rules carried further latent bugs (index written to a hardcoded shared path instead of the declared output). Delete the rules and the chain/levio_exe config options. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The manifest can now carry ref and ref_name columns so each sample can use its own reference; the two-column manifest with config-level values keeps working, and a '.' cell falls back to the config value. Chromosome names and lengths come only from each sample's BAM header, in header order (the sort order of the data), and a generated per-sample genome file replaces the fai for all bedtools and bigtools sizes arguments (with a parse-time staleness guard, so a leftover genome file can never disagree with its bam header). All reference and chromosome lookups are functions of the sm wildcard. Includes the fixes from the multi-agent code review (manifest cells parsed as literal text, config-specific errors for null ref values, sample-attributed test assertions). Supersedes #44. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
7e8a41f to
32b9e5d
Compare
|
Restructured into a 3-PR stack: #69 ( |
ddddc80 to
55ac52e
Compare
Summary
sample,bam,ref,ref_name. Each sample can use its own reference genome.refandref_namefor all samples. A.cell in the new columns falls back to the config value for that row. Filled manifest cells override config values (with an INFO line)..fai. A BAM whose contigs are a subset of its fasta now works instead of producing silently empty per-chromosome output.genome_filerule writes a per-sample chrom.sizes file from the BAM header; all bedtools/bigtools sizes arguments use it. The fasta/fai remain only as true references (CRAM encoding, mosdepth).{sm}wildcard (get_ref(wc),get_ref_name(wc),get_chroms(wc),get_excludes(wc)), backed by anlru_cached pysam header reader. Manifest validation runs at parse time withFIRE:-prefixed errors (duplicate samples, pairing rules, malformed rows, missing ref/fai/bam).ref_nameinto itsgenomes.txt; the hg38/GRCh38 auto-excludes are keyed per sample.Supersedes #44 (reimplemented from scratch per review feedback there: BAM header as the only chromosome source,
{sm}-keyed lookups, no dead code).Behavior change
Because chromosome lists are needed to build the DAG, every snakemake invocation (including dry-runs) now opens all manifest BAMs. Previously a completed run tolerated archived input BAMs. This mirrors the existing parse-time ref/fai checks and is documented in
config/README.md.Testing
pixi run test-dry(new, runs first in CI): 21-check dry-run matrix — back-compat, 4-column, sentinel, override-INFO, levio parse coverage, and one error fixture per validator branch, plus rendered-shell assertions covering both excludes branches.pixi run test+pixi run test-verify(new in CI): the single-sample regression completes 49/49 rules with golden counts identical to main (1,181-line peaks file, 46,223 fire elements) — the chromosome-source swap is behaviorally invisible.pixi run test-multi(new, local): full three-sample run (136/136 rules) with per-samplegenomes.txt(hg38/testref/testref2via sentinel), the empty-excludes branch, and a generated chr20-only BAM proving per-sample chromosome sets.Notes for review
pixi run fmtreformatted shell blocks across the workflow — mechanical whitespace noise beyond the functional changes. Two pre-existing((cat $(...)subshells infire-peaks.smkwere disambiguated to( (cat ...(shfmt correctly rejects the former as arithmetic).rule firestopped producing a bam, and a single globalchain:cannot coexist with per-sample references.test-verify's numbers may need hardening from this PR's first CI run.🤖 Generated with Claude Code
https://claude.ai/code/session_01NMLEvpsc6e62iPmUQKQz6E