Similarity
magenpy.stats.ld.similarity
¶
Compare GWAS summary statistics with candidate LD reference panels.
The public entry point, :func:compute_ld_sumstats_similarity, supports two
input modes:
- regional or chromosome-wise comparison of one summary-statistics table with
several :class:
~magenpy.LDMatrix.LDMatrixobjects; and - genome-wide comparison of several harmonized
:class:
~magenpy.GWADataLoader.GWADataLoaderobjects.
Both modes follow the same pipeline: harmonize alleles and variants, select a small shared set of genomic blocks, score each candidate using allele frequencies or an LD-based Gaussian likelihood, and convert the scores into relative probabilities with a softmax transformation.
_normalise_candidates(candidates, labels, candidate_type, name)
¶
Convert candidate inputs and their labels to validated parallel lists.
A mapping is treated as label -> candidate. For any other iterable,
labels are either supplied separately or generated as candidate_0,
candidate_1, and so on.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
candidates
|
Mapping or iterable containing candidate objects. |
required | |
labels
|
Optional labels for candidates supplied as an iterable. |
required | |
candidate_type
|
Required class for every candidate object. |
required | |
name
|
Human-readable candidate type used in error messages. |
required |
Returns:
| Type | Description |
|---|---|
|
A tuple |
Raises:
| Type | Description |
|---|---|
ValueError
|
If inputs are empty, labels are duplicated, or the number of labels does not match the number of candidates. |
TypeError
|
If a candidate has the wrong type. |
Source code in magenpy/stats/ld/similarity.py
_prepare_inputs(sumstats, ld_matrices, labels)
¶
Validate and normalize regional or chromosome-wise inputs.
The function copies summary statistics so that deriving Z scores and
normalizing chromosome labels never mutates the caller's object. If a
:class:SumstatsTable lacks an explicit Z column, its standard
z_score property is used to derive one when possible.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sumstats
|
A SumstatsTable or pandas DataFrame. |
required | |
ld_matrices
|
Candidate LDMatrix objects, as an iterable or a mapping from labels to matrices. |
required | |
labels
|
Optional labels when |
required |
Returns:
| Type | Description |
|---|---|
|
A tuple |
Raises:
| Type | Description |
|---|---|
TypeError
|
If summary statistics or LD candidates have invalid types. |
ValueError
|
If candidate LD matrices refer to different chromosomes. |
Source code in magenpy/stats/ld/similarity.py
_prepare_data_loaders(data_loaders, labels)
¶
Extract chromosome-specific inputs from harmonized data loaders.
Only chromosomes represented by both LD and summary statistics in every
loader are retained. Chromosome labels are matched with
:func:match_chromosomes, so common encodings such as 1 and chr1
are treated as equivalent. For each retained chromosome, summary
statistics from the first loader are harmonized against every candidate LD
matrix; variants absent from any candidate are removed later by
:func:_align_sumstats.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data_loaders
|
Candidate GWADataLoader objects, as an iterable or a
mapping from labels to loaders. Each loader must contain |
required | |
labels
|
Optional labels when |
required |
Returns:
| Type | Description |
|---|---|
|
A tuple |
Raises:
| Type | Description |
|---|---|
ValueError
|
If a loader lacks LD or summary statistics, or no chromosome is common to all loaders. |
Source code in magenpy/stats/ld/similarity.py
_align_sumstats(sumstats, ld_matrices)
¶
Harmonize summary statistics to LD panels and retain common variants.
:func:merge_snp_tables performs identifier matching, allele-flip
correction for signed statistics and MAF, and duplicate removal. Each
returned DataFrame uses the allele coding of its corresponding LD matrix,
but all frames contain the same summary-statistics variants in the same
physical order.
Two bookkeeping columns are added:
LD_INDEXis the variant's index in the underlying, unmasked LD store; it permits efficient block retrieval without changing an LDMatrix mask.LD_POSis the base-pair position used to sort shared variants.
LD_MAF is also added when allele frequencies are stored with the LD
matrix.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sumstats
|
Summary-statistics DataFrame containing |
required | |
ld_matrices
|
Candidate LDMatrix objects for one genomic region. |
required |
Returns:
| Type | Description |
|---|---|
|
One aligned DataFrame per LD matrix. Rows correspond exactly across returned frames. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If summary statistics lack allele or variant identifier columns. |
Source code in magenpy/stats/ld/similarity.py
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 | |
_select_blocks(n_variants, block_size, n_blocks)
¶
Select evenly distributed, non-overlapping blocks of variant indices.
Variants must already be sorted by genomic position. The full sequence is
divided into up to n_blocks segments. If a segment contains more than
block_size variants, its centered block_size variants are retained.
Centering avoids consistently favoring the left edge of each segment.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_variants
|
Number of ordered, usable variants in the region. |
required | |
block_size
|
Maximum number of variants retained per block. |
required | |
n_blocks
|
Maximum number of blocks to return. |
required |
Returns:
| Type | Description |
|---|---|
|
A list of integer index arrays. Blocks do not overlap and each has
at most |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in magenpy/stats/ld/similarity.py
_valid_variants(aligned, method)
¶
Find variants with valid inputs in every candidate panel.
Frequency scoring requires finite MAF and LD_MAF values in [0, 1]
for every candidate. LD-likelihood scoring requires finite Z scores for
every candidate. Requiring joint validity preserves a fair comparison.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
aligned
|
Candidate DataFrames returned by :func: |
required | |
method
|
|
required |
Returns:
| Type | Description |
|---|---|
|
A shared boolean validity mask, or |
Source code in magenpy/stats/ld/similarity.py
_frequency_scores(aligned, af_scale, block_size, n_blocks)
¶
Score one region using allele-frequency agreement.
For candidate k, the frequency distance is
RMSE_k = sqrt(mean((MAF_sumstats - MAF_LD_k) ** 2)).
Because :func:_align_sumstats orients summary-statistics MAF to each LD
panel first, the differences always compare frequencies of the same allele.
The similarity score is -0.5 * (RMSE_k / af_scale) ** 2; therefore,
larger scores (values closer to zero) indicate greater agreement.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
aligned
|
Candidate DataFrames for one region. |
required | |
af_scale
|
Frequency difference treated as one scoring unit. |
required | |
block_size
|
Maximum variants selected per block. |
required | |
n_blocks
|
Maximum blocks selected within this region. |
required |
Returns:
| Type | Description |
|---|---|
|
A tuple |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
Source code in magenpy/stats/ld/similarity.py
_load_ld_block(ldm, indices, visible_indices=None)
¶
Load a dense LD block for arbitrary stored variant indices.
The smallest contiguous span containing indices is loaded through
:meth:LDMatrix.load_data, which handles dequantization and symmetrization.
The requested (possibly non-contiguous) variants are then selected from the
span. This avoids materializing the full chromosome-wide LD matrix.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
ldm
|
Source LDMatrix. |
required | |
indices
|
Variant indices in the original on-disk LD store. |
required | |
visible_indices
|
Optional cached stored indices retained by the current LDMatrix mask. |
None
|
Returns:
| Type | Description |
|---|---|
|
A symmetric dense NumPy array ordered like |
Source code in magenpy/stats/ld/similarity.py
_ld_likelihood_scores(aligned, ld_matrices, block_size, n_blocks, regularization, z_clip)
¶
Score one region using the likelihood of its GWAS Z scores.
For every selected block and candidate panel, this function evaluates
Z_block ~ MVN(0, (1 - regularization) * R + regularization * I),
where R is the candidate LD block. Regularization improves numerical
stability and reduces sensitivity to reference-panel sampling noise. Block
log-likelihoods are summed and divided by the total number of selected
variants, making scores comparable when fewer than the requested number of
variants is available.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
aligned
|
Candidate DataFrames for one region. |
required | |
ld_matrices
|
LDMatrix corresponding to each aligned DataFrame. |
required | |
block_size
|
Maximum variants selected per block. |
required | |
n_blocks
|
Maximum blocks selected within this region. |
required | |
regularization
|
Weight of the identity matrix in the regularized LD
covariance; must be in |
required | |
z_clip
|
Optional symmetric bound applied to Z scores before scoring. |
required |
Returns:
| Type | Description |
|---|---|
|
A tuple |
Raises:
| Type | Description |
|---|---|
ValueError
|
If Z scores are unavailable, regularization is invalid, or an LD block remains non-positive-semidefinite. |
Source code in magenpy/stats/ld/similarity.py
456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 | |
_allocate_blocks(regions, method, n_blocks)
¶
Allocate a genome-wide block budget across chromosome regions.
The method-specific usable-variant counts are concatenated conceptually in
chromosome order. n_blocks evenly spaced midpoint targets are placed on
that genome-wide axis, and each target is assigned to its containing
chromosome. Consequently, chromosomes receive blocks approximately in
proportion to their usable variant counts, and no block can cross a
chromosome boundary.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
regions
|
Aligned candidate DataFrames grouped by chromosome. |
required | |
method
|
|
required | |
n_blocks
|
Total block budget across all regions. |
required |
Returns:
| Type | Description |
|---|---|
|
Integer array containing the number of blocks allocated to each
region. Its sum is |
Source code in magenpy/stats/ld/similarity.py
_score_regions(regions, matrix_regions, method, af_scale, block_size, n_blocks, regularization, z_clip)
¶
Score and aggregate one or more chromosome regions.
This is the common scoring path for both public input modes. A regional
request supplies one element in regions; a genome-wide request supplies
one per common chromosome.
Regional frequency RMSE values are combined by accumulating squared error weighted by the number of selected variants, then taking a genome-wide square root. Regional LD scores are mean log-likelihoods, so they are converted back to log-likelihood sums before aggregation and divided by the genome-wide selected-variant count at the end.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
regions
|
Sequence of chromosome regions. Each region is a list of aligned candidate DataFrames. |
required | |
matrix_regions
|
Sequence matching |
required | |
method
|
|
required | |
af_scale
|
Frequency-score scale passed to :func: |
required | |
block_size
|
Maximum variants selected per block. |
required | |
n_blocks
|
Total block budget across all regions. |
required | |
regularization
|
LD covariance regularization weight. |
required | |
z_clip
|
Optional Z-score clipping threshold. |
required |
Returns:
| Type | Description |
|---|---|
|
A tuple |
Source code in magenpy/stats/ld/similarity.py
compute_ld_sumstats_similarity(sumstats=None, ld_matrices=None, labels=None, method='auto', *, data_loaders=None, priors=None, temperature=1.0, af_scale=0.05, block_size=150, n_blocks=5, min_variants=20, regularization=0.05, z_clip=8.0)
¶
Measure relative agreement between GWAS summary statistics and LD panels.
There are two mutually exclusive input modes:
- Regional/chromosome-wise: Pass one
sumstatsobject and candidateld_matrices. Every LD matrix must describe the same region or chromosome. - Genome-wide: Pass candidate
data_loaders. Each GWADataLoader must contain LD and summary statistics that have already been harmonized internally. Only chromosomes available in every loader are compared.
Genome-wide blocks are allocated across chromosomes approximately in proportion to the number of usable variants and never span chromosome boundaries. In either mode, candidates are compared using exactly the same summary-statistics variants.
Scoring methods
method="frequency" compares allele-aligned A1 frequencies using RMSE.
The returned score is -0.5 * (RMSE / af_scale) ** 2.
method="ld_likelihood" treats the Z scores in each selected block as
multivariate normal with covariance given by the regularized candidate LD
matrix. Its score is the mean log-likelihood per selected variant.
method="auto" first attempts frequency scoring. It falls back to LD
likelihood when fewer than min_variants frequency-complete variants
can be selected.
Both methods select up to n_blocks blocks with at most block_size
variants each. min_variants applies to the total selected across all
blocks and, in genome-wide mode, across all chromosomes.
Candidate probabilities are calculated as
softmax(score / temperature + log(prior)). They express relative
evidence only among the supplied candidates; they are not calibrated
ancestry posterior probabilities. In particular, omitting the true or a
closely related reference population can make the largest probability
misleadingly high.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sumstats
|
Regional/chromosome summary statistics as a SumstatsTable
or pandas DataFrame. |
None
|
|
ld_matrices
|
Candidate regional/chromosome LDMatrix objects. May be
an iterable or a |
None
|
|
labels
|
Optional unique candidate labels when |
None
|
|
method
|
Scoring method: |
'auto'
|
|
data_loaders
|
Harmonized GWADataLoader candidates for genome-wide
scoring. May be an iterable or a |
None
|
|
priors
|
Optional positive prior weights. Supply one per candidate in candidate order, or a mapping keyed by candidate label. Uniform priors are used by default. |
None
|
|
temperature
|
Positive softmax temperature. Values above one produce less concentrated relative probabilities; values below one produce more concentrated probabilities. |
1.0
|
|
af_scale
|
Allele-frequency RMSE corresponding to one unit in the frequency score. Smaller values penalize discrepancies more strongly. |
0.05
|
|
block_size
|
Maximum number of variants selected per block. Must be at least two. |
150
|
|
n_blocks
|
Maximum number of blocks across the entire comparison. This is a genome-wide total in data-loader mode, not a per-chromosome value. |
5
|
|
min_variants
|
Minimum total variants selected across all blocks. |
20
|
|
regularization
|
Identity-matrix weight in the LD covariance
|
0.05
|
|
z_clip
|
Optional positive symmetric clipping threshold for Z scores.
Set to |
8.0
|
Returns:
| Type | Description |
|---|---|
|
A DataFrame indexed by candidate label and sorted by decreasing
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If input modes are mixed, parameters are invalid, too few usable variants are found, or scores cannot be computed. Examples¶Regional or chromosome-wise comparison:: Genome-wide comparison:: |
Source code in magenpy/stats/ld/similarity.py
656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 | |