Skip to content

NaN's in ld_matrix output with "ghost" alleles #3474

Description

@nspope

Here's a MWE:

# /// script                                                                                                                                                   
# dependencies = ["tskit==1.0.3"]
# requires-python = ">=3.13"
# ///
import tskit

tables = tskit.TableCollection(sequence_length=10)
for _ in range(4):
    tables.nodes.add_row(flags=tskit.NODE_IS_SAMPLE, time=0)
tables.nodes.add_row(flags=0, time=1)  # node 4: parent of samples 0,1
tables.nodes.add_row(flags=0, time=2)  # node 5: root
for parent, child in [(4, 0), (4, 1), (5, 4), (5, 2), (5, 3)]:
    tables.edges.add_row(left=0, right=10, parent=parent, child=child)

# Site 0: A -> G then G -> T stacked on node 4 
# (so "G" is in the allele list but carried by zero samples)
s0 = tables.sites.add_row(position=2, ancestral_state="A")
mG = tables.mutations.add_row(site=s0, node=4, derived_state="G", time=1.5)
tables.mutations.add_row(site=s0, node=4, derived_state="T", time=1.2, parent=mG)

# Site 1: plain biallelic A -> C on node 4
s1 = tables.sites.add_row(position=6, ancestral_state="A")
tables.mutations.add_row(site=s1, node=4, derived_state="C", time=1.5)

# Site 2: plain biallelic A -> G on node 4
s2 = tables.sites.add_row(position=8, ancestral_state="A")
tables.mutations.add_row(site=s2, node=4, derived_state="G", time=1.5)

tables.sort()
ts = tables.tree_sequence()

print(f"\n---\ntree sequence:")
print(ts.draw_text())

print("\n---\nsites:")
for v in ts.variants():
    print(f"site {v.site.id}: alleles={v.alleles} genotypes={v.genotypes.tolist()}")

print("\n---\nstats (sites 0, 1):")
for stat in ["D", "r", "r2", "D_prime", "D2"]:
    print(f"{stat:8s} = {ts.ld_matrix(sites=[[0], [1]], stat=stat)[0, 0]}")

print("\n---\nstats (sites 1, 2):")
for stat in ["D", "r", "r2", "D_prime", "D2"]:
    print(f"{stat:8s} = {ts.ld_matrix(sites=[[1], [2]], stat=stat)[0, 0]}")   

Output:

#---                                                                                                                                                            
#tree sequence:                                                                                                                                                 
#2.00┊     5   ┊                                                                                                                                                
#    ┊  ┏━━╋━┓ ┊                                                                                                                                                
#1.00┊  4  ┃ ┃ ┊                                                                                                                                                
#    ┊ ┏┻┓ ┃ ┃ ┊                                                                                                                                                
#0.00┊ 0 1 2 3 ┊                                                                                                                                                
#    0        10                                                                                                                                                                                                                                                                                                               
#                                                                                                                                                               
---
sites:
site 0: alleles=('A', 'G', 'T') genotypes=[2, 2, 0, 0]
site 1: alleles=('A', 'C') genotypes=[1, 1, 0, 0]
site 2: alleles=('A', 'G') genotypes=[1, 1, 0, 0]

---
stats (sites 0, 1):
D        = 0.125
r        = nan
r2       = nan
D_prime  = nan
D2       = 0.041666666666666664

---
stats (sites 1, 2):
D        = 0.25
r        = 1.0
r2       = 1.0
D_prime  = 1.0
D2       = 0.0625

Given the stats that get NaN'd are the normalised ones, I'm assuming this is a division-by-zero somewhere in the normalisation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions