Skip to content

Commit 2ab912c

Browse files
committed
Make sure that variant.count() returns alleles in an order
And document/test it.
1 parent 300ea4f commit 2ab912c

3 files changed

Lines changed: 11 additions & 3 deletions

File tree

python/CHANGELOG.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
- CLI commands that load a tree sequence now read from stdin when the input
88
path argument is omitted. (:user:`chris-a-talbot`, :user:`jeromekelleher`,
99
:issue:`3468`, :pr:`3469`)
10+
- The returned object from ``variant.counts()`` and ``variant.frequencies()``
11+
now stores alleles in the order defined in ``variant.alleles``.
12+
(:user:`hyanwong`, :pr:`3471`)
1013

1114
--------------------
1215
[1.0.3] - 2026-05-14

python/tests/test_genotypes.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2609,7 +2609,7 @@ def test_variant_counts(self, ts_fixture):
26092609
assert len(variant.alleles) > 2
26102610
assert None in variant.alleles
26112611
counts = variant.counts()
2612-
assert len(counts) == len(variant.alleles)
2612+
assert list(counts.keys()) == list(variant.alleles)
26132613
assert np.sum(list(counts.values())) == ts_fixture.num_samples
26142614
assert counts[None] == variant.num_missing
26152615
assert ts_fixture.num_samples > variant.num_missing

python/tskit/genotypes.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -283,16 +283,19 @@ def counts(self) -> typing.Counter[str | None]:
283283
possible :attr:`allele <Variant.alleles>` at this site: i.e. the number of
284284
samples possessing that allele among the set of samples specified when creating
285285
this Variant (by default, this is all the sample nodes in the tree sequence).
286-
Missing data is represented by an allelic state of ``None``.
286+
Missing data is represented by an allelic state of ``None``. The order of
287+
alleles in the Counter is the same as the order of alleles in the
288+
:attr:`alleles <Variant.alleles>` tuple.
287289
288290
:return: A counter of the number of samples associated with each allele.
289291
"""
290292
counts = collections.Counter()
291293
if self.alleles[-1] is None:
292294
# we have to treat the last element of the genotypes array as special
293-
counts[None] = np.sum(self.genotypes == tskit.MISSING_DATA)
294295
for i, allele in enumerate(self.alleles[:-1]):
295296
counts[allele] = np.sum(self.genotypes == i)
297+
# Add the count of missing data as the last item
298+
counts[None] = np.sum(self.genotypes == tskit.MISSING_DATA)
296299
else:
297300
bincounts = np.bincount(self.genotypes, minlength=self.num_alleles)
298301
for i, allele in enumerate(self.alleles):
@@ -308,6 +311,8 @@ def frequencies(self, remove_missing=None) -> dict[str, float]:
308311
sample nodes in the tree sequence). Note, therefore, that if a restricted set
309312
of samples was specified on creation, the allele frequencies returned here
310313
will *not* be the global allele frequencies in the whole tree sequence.
314+
The order of alleles in the returned dictionary is the same as the order
315+
of alleles in the :attr:`alleles <Variant.alleles>` tuple.
311316
312317
:param bool remove_missing: If True, only samples with non-missing data will
313318
be counted in the total number of samples used to calculate the frequency,

0 commit comments

Comments
 (0)