Skip to content

Phased attribute to HaplotypeMatrix and warnings in phase-dependent statistics. - #401

Merged
andrewkern merged 7 commits into
kr-colab:mainfrom
mufernando:phase-stats
Nov 7, 2026
Merged

andrewkern merged 7 commits into
kr-colab:mainfrom
mufernando:phase-stats

Conversation

@mufernando

Copy link
Copy Markdown
Member

This addresses #168.

Haplotype_Matrix, which is the main pg-gpu data structure, did not have a notion of phase. This is critical because a lot of statistics can only be run with phased data, whereas others work either way. This is already dealt with at some level, e.g. with pca vs pca_dosage, but I think it's important for users to be warned if they try to compute phase-dependent statistics on unphased data.

The changelog summarizes all the changes well, I think:

Added phased attribute to HaplotypeMatrix (which defaults to
False). This tracks whether the haplotypes in the matrix
represent true phased haplotypes or not. Each loader exposes a
phased keyword argument: from_vcf and from_zarr default
to False; from_ts defaults to True. It is possible to
call set_phased() or set_unphased() to change it after
construction.

Statistics that depend on phased haplotypes emit an
UnphasedDataWarning when given a HaplotypeMatrix with
phased=False. These include Garud's H, iHS, XP-EHH, nSL,
haplotype counts and diversity, haplotype r² and D, distance
statistics between haplotypes, PCA and local PCA on haplotypes, and the
windowed scans that request any of these. Each call warns once and it
names an unphased alternative where one exists. For
garud_h, pairwise_diffs, the dist_* moments, zns and
omega, the unphased alternative is to pass a GenotypeMatrix.
One small wrinkle: moments_ld.compute_ld_statistics with
vcf_file= and use_genotypes=False now loads the VCF as phased,
just to avoid the unphased data warning. See :doc:phasing for the full
list of statistics and how to silence the warning.

Because from_vcf, from_zarr, the raw HaplotypeMatrix(...)
constructor, and GenotypeMatrix.to_haplotype_matrix all give
phased=False, going forward all code that uses phased data without
explicitly marking it as phased will start to see this warning. Load
with phased=True or call set_phased() after loading.

@mufernando
mufernando requested a review from nspope November 6, 2026 23:10

@andrewkern andrewkern left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great to me. A couple findings:

  1. Needs a rebase: windowed_analysis.py conflicts with main in two hunks (keep both sides). After rebasing, pixi run check-map fails on 6 map entries: the new phased param on HaplotypeMatrix.__init__, from_vcf, from_zarr, from_ts, and phased/set_phased/set_unphased on both haplotype matrix classes in docs/dev/pipeline_map.toml.
  2. The pyproject.toml edit changes the hash of the editable pg_gpu entry in pixi.lock, so CI's locked install will fail until you run pixi lock and commit the lock.
  3. Lint: tests/test_unphased_warning.py has two E402s and an E731.
  4. Since we require Python 3.12, _skip_phase_wrappers can be replaced by warnings.warn(..., skip_file_prefixes=(os.path.dirname(pg_gpu.__file__) + os.sep,)). I checked it gives the same warning locations on 11 paths, and it removes the frame walk and the hard-coded stacklevels (the ContextVar depth counter is still needed).
  5. to_zarr then from_zarr drops the flag, so a from_ts matrix saved to zarr comes back unphased. Writing and reading VCZ's call_genotype_phased would keep it; fine as a follow-up.

@mufernando

Copy link
Copy Markdown
Member Author

I addressed your concerns, @andrewkern! I'll let you squash when merging.

@andrewkern
andrewkern merged commit 53ea50b into kr-colab:main Nov 7, 2026
2 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.

2 participants