Skip to content

fix: guard missing/unresolvable taxonomy in annotate/train + deterministic species selection - #97

Open
vinvomero wants to merge 1 commit into
nextgenusfs:mainfrom
vinvomero:fix/annotate-train-taxonomy-guard
Open

fix: guard missing/unresolvable taxonomy in annotate/train + deterministic species selection#97
vinvomero wants to merge 1 commit into
nextgenusfs:mainfrom
vinvomero:fix/annotate-train-taxonomy-guard

Conversation

@vinvomero

Copy link
Copy Markdown
Contributor

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 taxonomy
straight into choose_best_busco_species / choose_best_augustus_species. So:

  • a False taxonomy (JGI lookup AND training-data taxonomy both unavailable)
    crashes with argument of type 'bool' is not iterable; and
  • a non-matching taxonomy falls through best_taxonomy's random.choice() tie-break
    -- 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, which
    then exits 1 inside the augustus binary.

Fix

  • New augustus_species_from_taxonomy() -- the Augustus analog of the existing
    busco_lineage_from_taxonomy(). It delegates the FULL taxonomy to
    choose_best_augustus_species (Augustus scores all levels, exact=False), so
    resolvable inputs are byte-identical; guards falsy/non-overlapping taxonomy with
    a deterministic default + loud warning; 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, key=str.lower)[0]
    instead of random.choice -- so selection is reproducible run-to-run. This is shared
    with the busco path; it only changes previously-random tie outcomes, and key=str.lower
    avoids 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_species remains the escape hatch (unchanged).

Tests

Extends tests/unit/test_utilities_taxonomy.py: falsy/empty -> default, byte-identical
delegation 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).

…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>
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