Skip to content

resolve GTDB taxid hash collisions deterministically - #7

Merged
alpae merged 2 commits into
mainfrom
fix-taxid-collisions
Oct 16, 2026
Merged

alpae merged 2 commits into
mainfrom
fix-taxid-collisions

Conversation

@alpae

@alpae alpae commented Oct 16, 2026

Copy link
Copy Markdown
Member

GTDB taxids are a 31bit hash of the taxon name or genome accession
number. With >1.1M keys in r232, 318 taxids were shared by two keys;
the entry written last silently replaced the other, which then could
not be found anymore, and in case of taxon names, its genomes got
attached to an unrelated node.

Taxids are now assigned jointly for all domains of a release: if several
keys hash to the same value, the alphabetically first keeps it, the
others get the first unused hash_to_int(f"{key}#{n}"), processed in
alphabetical order. Non-colliding taxids are unchanged and the result
only depends on the GTDB release. Bump DB_VERSION to trigger a rebuild
of existing databases.

This should fix the issue #6

GTDB taxids are a 31bit hash of the taxon name or genome accession
number. With >1.1M keys in r232, 318 taxids were shared by two keys;
the entry written last silently replaced the other, which then could
not be found anymore, and in case of taxon names, its genomes got
attached to an unrelated node.

Taxids are now assigned jointly for all domains of a release: if several
keys hash to the same value, the alphabetically first keeps it, the
others get the first unused hash_to_int(f"{key}#{n}"), processed in
alphabetical order. Non-colliding taxids are unchanged and the result
only depends on the GTDB release. Bump DB_VERSION to trigger a rebuild
of existing databases.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Rebuilding from legacy dump archives can preserve collisions while marking the database current.

1 open finding
What changed in this PR

Resolves GTDB taxid hash collisions deterministically to prevent lost taxa and incorrect lineages, addressing issue #6.

Changes:

  • Assigns unique taxids jointly across domains while preserving non-colliding IDs.
  • Bumps the database version and versions the test cache.
  • Adds allocation and real-release collision regression tests.
File Description
tests/​test_gtdb.py Tests deterministic allocation and collision handling.
tests/​conftest.py Includes database version in the test cache path.
omataxonomy/​query.py Bumps the database version to trigger rebuilding.
omataxonomy/​gtdb.py Resolves collisions across jointly processed domains.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread omataxonomy/query.py Resolved
Archives built before hash collisions were resolved still contain
duplicated GTDB taxids. update_db only generates a new archive if none
exists, so after the DB_VERSION bump an old omatax.tar.gz next to the
database (or passed explicitly) would be loaded again, silently drop
the colliding taxa and still be marked as up to date.

load_tree_from_dump now raises a ValueError if nodes.dmp contains a
taxid more than once, before the database is touched.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟢 Approval recommended

No unresolved issues remain; deterministic allocation and duplicate-archive rejection address the reported data loss.

0 open findings

1 resolved since last review

🧠 Review effort: Balanced

@alpae
alpae merged commit 6c35dc4 into main Oct 16, 2026
20 checks passed
@alpae
alpae deleted the fix-taxid-collisions branch October 16, 2026 11:54
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