Skip to content

feat(region): UCSC<->Ensembl chromosome-name aliasing for -r#78

Merged
balwierz merged 1 commit into
mainfrom
fix/chrom-name-normalization
Jul 9, 2026
Merged

feat(region): UCSC<->Ensembl chromosome-name aliasing for -r#78
balwierz merged 1 commit into
mainfrom
fix/chrom-name-normalization

Conversation

@balwierz

@balwierz balwierz commented Jul 9, 2026

Copy link
Copy Markdown
Owner

Summary

A -r chr1:… query against a file that names the contig 1 (or vice versa) silently returned zero rows — the classic UCSC-vs-Ensembl naming footgun a bioinformatician hits constantly. vv now retries with the counterpart name when the queried chromosome isn't present but its alias is, noting the swap on stderr.

Scoped deliberately (per the constraints): only human and mouse standard chromosomes are aliased — autosomes 122 (covers human 1-22 and mouse 1-19), X, Y, and the mitochondrion chrMMT (never bare M). Scaffolds, patches, and alt-contigs are never remapped, so a genuine typo (e.g. chr99) still errors/empties exactly as before.

chrom_alias() + a templated resolve_chrom() / resolve_region_chroms() resolve each region window's chromosome against the file's own contig list, applied where each source knows its contigs:

  • tabix (.vcf.gz/.bed.gz/.gff.gz/.tsv.gz) via tbx_seqnames
  • BCF via bcf_hdr_name2id
  • BAM --pileup via bam_name2id
  • LociSSD v4 via rank_to_name

Generic-Parquet and bigWig region paths (which don't carry a cheap contig list) are a noted follow-up.

$ vv variants.vcf.gz -r chr1:1000-2000     # file uses '1'
vv: variants.vcf.gz: region chromosome 'chr1' not found; using '1' (UCSC/Ensembl naming)
… rows …

Verification

  • New Ensembl-named fixture tiny.ens.bed.gz (contigs 1, MT).
  • Tests: 1chr1 on LociSSD v4 / tabix VCF / BCF (equal row counts); the chrMMT special case; the reverse chr11; and that a non-standard chr99 is not remapped (0 rows). Suite 370.
  • Man page + CHANGELOG updated.

🤖 Generated with Claude Code

A `-r chr1:…` query against a file that names the contig `1` (or vice versa)
silently returned zero rows — the classic UCSC-vs-Ensembl footgun. When the
queried chromosome isn't a contig the file has but its counterpart is, vv now
retries with the alias and notes the swap on stderr.

Scoped deliberately: only HUMAN and MOUSE standard chromosomes are aliased —
autosomes 1..22 (covers human 1-22 and mouse 1-19), X, Y, and the mitochondrion
`chrM` <-> `MT` (never bare `M`). Scaffolds, patches and alt-contigs are never
remapped, so a genuine typo (e.g. chr99) still errors/empties as before.

`chrom_alias()` + a templated `resolve_chrom()`/`resolve_region_chroms()` resolve
each window's chromosome against the file's own contig list, applied where each
source knows its contigs: tabix (`tbx_seqnames`), BCF (`bcf_hdr_name2id`), BAM
`--pileup` (`bam_name2id`), and LociSSD v4 (`rank_to_name`). Generic-Parquet and
bigWig region paths (no cheap contig list) are a noted follow-up.

New Ensembl-named fixture tiny.ens.bed.gz (contigs `1`, `MT`) + tests covering
both directions, the chrM<->MT special case, and that non-standard names aren't
remapped. Suite 370.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@balwierz
balwierz merged commit 501dc67 into main Jul 9, 2026
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant