fix: guard missing/unresolvable taxonomy in annotate/train + deterministic species selection - #97
Open
vinvomero wants to merge 1 commit into
Open
Conversation
…istic species selection annotate() and train() passed taxonomy straight into choose_best_busco_species / choose_best_augustus_species, so a False taxonomy (JGI lookup and training-data both unavailable) crashed, and a non-matching taxonomy fell through best_taxonomy's random.choice() tie-break -- the "randomly picks a wrong Augustus species" path behind nextgenusfs#60 (whose log shows a valid taxonomy resolving to `augustus --species=elephant_shark`, which then crashes the augustus binary). This is the un-adopted sibling of the merged predict() fix (nextgenusfs#94): - add augustus_species_from_taxonomy(), the Augustus analog of busco_lineage_from_taxonomy(); it delegates to choose_best_augustus_species with the full taxonomy (Augustus scores all levels, exact=False) so working inputs are byte-identical, guards falsy/no-overlap taxonomy with a deterministic default, and always returns a valid augustus_species key. - route the busco sites in annotate()/train() through busco_lineage_from_taxonomy(..., default=None) with the same warn+default pattern predict() already uses. - make best_taxonomy's tie-break deterministic (sorted(best_matches)[0] instead of random.choice) so species/lineage selection is reproducible. Extends tests/unit/test_utilities_taxonomy.py with Augustus sibling coverage (falsy/empty -> default, byte-identical delegation on working inputs, deterministic tie-break, default=None sentinel). Addresses nextgenusfs#60 (refs nextgenusfs#32). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ports the merged predict() taxonomy fix (#94) to the two entry points that never
adopted it, and makes species/lineage selection deterministic.
Problem
predict() was hardened in #94, but annotate() and train() still pass
taxonomystraight into choose_best_busco_species / choose_best_augustus_species. So:
Falsetaxonomy (JGI lookup AND training-data taxonomy both unavailable)crashes with
argument of type 'bool' is not iterable; and-- the "randomly picks a wrong Augustus species" path behind Problem on finding best augustus species #60, whose log
shows a valid taxonomy resolving to
augustus --species=elephant_shark, whichthen exits 1 inside the augustus binary.
Fix
augustus_species_from_taxonomy()-- the Augustus analog of the existingbusco_lineage_from_taxonomy(). It delegates the FULL taxonomy tochoose_best_augustus_species(Augustus scores all levels, exact=False), soresolvable inputs are byte-identical; guards falsy/non-overlapping taxonomy with
a deterministic default + loud warning; always returns a valid augustus_species key.
busco_lineage_from_taxonomy(..., default=None)with the same warn+default patternpredict() already uses.
sorted(best_matches, key=str.lower)[0]instead of
random.choice-- so selection is reproducible run-to-run. This is sharedwith the busco path; it only changes previously-random tie outcomes, and
key=str.loweravoids a lexical bias toward the capitalized reference keys.
On #60
This makes the Augustus pick deterministic (no more random elephant_shark) and guards
the crash class. Whether a deterministic default species actually RUNS to completion for
an exotic non-fungal genome depends on the augustus binary -- hence "addresses" rather
than "fixes". For off-label genomes,
--augustus_speciesremains the escape hatch (unchanged).Tests
Extends
tests/unit/test_utilities_taxonomy.py: falsy/empty -> default, byte-identicaldelegation on working inputs (verified across all 100 augustus reference taxa),
deterministic + case-insensitive tie-break, overlap-gate default on malformed partial
taxonomy, default=None sentinel.
Addresses #60 (refs #32).