Skip to content

Make --taxonomy select the priors it names - #6

Merged
traviswheeler merged 1 commit into
mainfrom
fix_taxonomy_priors
Aug 14, 2026
Merged

Make --taxonomy select the priors it names#6
traviswheeler merged 1 commit into
mainfrom
fix_taxonomy_priors

Conversation

@traviswheeler

@traviswheeler traviswheeler commented Aug 14, 2026

Copy link
Copy Markdown
Member

What was broken

lineage_paths() required One_Hop_Refilled_*.json and Two_Hop_Refilled_*.json under ONE_HOP_NEIGHBOR_DATA and TWO_HOP_NEIGHBOR_DATA. Neither directory is present, and it looks like neither was ever part of the code. The check therefore failed for every taxonomy, including the default, and every run loaded domain-level priors. The two paths were returned and never read, so nothing failed and nothing appeared in the log beyond a note on stderr.

Four runs of the released 0.1.5 container on one input, differing only in -t:

DEFAULT                                23fac15045dd42ca4c1296e16927697a
cyanobacteriota                        23fac15045dd42ca4c1296e16927697a
cyanobacteriota_melainabacteria_group  23fac15045dd42ca4c1296e16927697a
actinomycetota                         23fac15045dd42ca4c1296e16927697a

actinomycetota_phylum_level_priors ships under exactly that name, with no mismatch, and it still fell back. That isolates the missing directories as the cause.

Three more problems in the same code

The hardcoded PHYLUM and KINGDOM sets had drifted from the files that ship:

  • cyanobacteriota was listed, but the file is cyanobacteriota_melainabacteria_group_phylum_level_priors
  • fusobacteriota_phylum_level_priors ships but appears in neither set
  • mycoplasmatota was listed as a kingdom, though the -ota suffix makes it a phylum

Those two prior sets stayed unreachable even once the file check was corrected.

What changed

The accepted names are read from the installed files instead of a hardcoded list, so they cannot disagree with what ships. The scan matches the filename pattern rather than listing the directory, since a README.md sits in both data directories.

A name may be shortened where exactly one canonical name extends it at an underscore, so cyanobacteriota reaches the melainabacteria group set and fcb reaches fcb_group, while cyano is refused.

An unrecognized name now causes an error. It lists the valid names grouped by rank, or names the near misses when the input is close to one:

[taxonomy] 'fusobacteri' is an unrecognized taxonomic group.
           Closest: fusobacteriati (kingdom), fusobacteriota (phylum)

The domain-level taxon is called bacteria, since every other entry in the list is a taxon rather than a rank. domain still works as input.

Logging reports the priors in use rather than the string the user typed. Those used to disagree: asking for cyanobacteriota logged cyanobacteriota while loading the domain file.

The one-hop and two-hop paths are removed from Paths and from the return value, since nothing read them.

Breaking change for anyone passing -t

A run that passed -t and silently got domain priors will now either produce different numbers, or stop with an error if the name is not recognized. Both are the intended fix, but results generated with -t before this change are not comparable to results generated after it. The 0.1.6 release notes should say so.

Results produced without -t are unaffected, since those were domain priors either way.

Test

tests/taxonomy_test.py, wired into CI, runs one input under four taxonomies and requires the results to differ. It fails against the current release. On this branch:

bacteria         b87288029d76f3dba1b1fc0343f6aa07
cyanobacteriota  8024f89606ddad0e1c317eef475cd85d
actinomycetota   0df9730fc101a63503caaf9d367e7798
bacillati        5cc0090877eb28aa71cc8efc9de801c6
ok   all 4 taxonomies gave distinct results (got 4 distinct)

It also checks that all 20 names round-trip, that every -ati name is a kingdom and every -ota name a phylum, that the two previously unreachable sets are reachable, and that an invalid name exits non-zero.

lineage_paths() required One_Hop_Refilled_*.json and Two_Hop_Refilled_*.json
under ONE_HOP_NEIGHBOR_DATA and TWO_HOP_NEIGHBOR_DATA. Neither directory is
present, and it looks like neither was ever part of the code, so the check
failed for every taxonomy including the default and every run loaded domain
priors. The two paths were returned and never read, so nothing failed. Four
runs of the 0.1.5 container differing only in -t produced byte identical
output.

Check only the counts table and the neighbour graph, the two files the code
reads.

The accepted names now come from the installed files rather than a hardcoded
list. The lists they replace had drifted three ways: they named
"cyanobacteriota" while the file is "cyanobacteriota_melainabacteria_group",
omitted "fusobacteriota", and filed "mycoplasmatota" as a kingdom though the
-ota suffix makes it a phylum. Two prior sets stayed unreachable even after
that check was corrected.

A name may be shortened where exactly one canonical name extends it at an
underscore, so "cyanobacteriota" and "fcb" resolve while "cyano" does not.
An unrecognized name causes an error that lists the valid names by rank, or
the near misses when the input is close to one. It used to select domain
priors in silence. The domain-level taxon is called bacteria, since every
other entry in the list is a taxon rather than a rank.

Logging reports the priors in use instead of the string the user typed. Those
disagreed: asking for cyanobacteriota logged cyanobacteriota while loading
the domain file.

tests/taxonomy_test.py runs one input under four taxonomies and requires the
results to differ. It fails against the current release.

Implemented with assistance from Claude (Opus 5)
@traviswheeler
traviswheeler merged commit d26ae7e into main Aug 14, 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.

1 participant