pyronear / pyronear/pyro-annotator

FP lane gaining missed-smoke stays annotated with no boxes, and exports

Open
#355 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
0
Forks
1
Avg merge
1d 2h
Merged PRs (30d)
2

Description

An FP lane sitting at annotated can gain missed-smoke — and therefore start needing localization — without changing stage, so neither the localization guard nor the FP→smoke demotion fires. The lane ends up at annotated, needing localization, with zero boxes: on /localize/done and in /export/alerts.

This is the state #346 set out to prevent. PR #352 closed every path into annotated; this one never crosses that boundary.

Reproduced

SEEDED:      [('annotated', {'annotation': []})]   # FP lane's empty placeholder
PATCH {"has_missed_smoke": true}
PATCH status: 200
RESULT stage: annotated
RESULT has_missed_smoke: True
IN /localize/done: True
IN /export/alerts: True

Why both guards miss it

  • The localization guard (sequence_annotations.py, assert_localization_complete) requires the stage to be changing into annotated. Here target_processing_stage == existing.processing_stage == ANNOTATED, so it is skipped. Widening it would not help either: the FP exit already wrote empty annotated-stage detection annotations via auto_create_detection_annotations, so assert_localization_complete would pass on those rows.
  • The FP→smoke promotion (is_fp_promotion) requires target_processing_stage == SEQ_ANNOTATION_DONE. A flags-only PATCH leaves the stage alone, so the demotion — which would delete those empty rows and re-arm auto-annotate — never runs.

Reachable from the UI, not just the API

frontend/src/pages/LocalizeAlertPage.tsx sends exactly this PATCH from the missed-smoke row:

apiClient.updateSequenceAnnotation(annotationId, { has_missed_smoke: value })

and missedSmokeAnnotationId falls back to "the first lane that has an annotation at all", which can be the FP lane. The row renders in done mode.

Suggested fix

Key is_fp_promotion on the flag transition rather than the target stage: a lane at annotated that did not previously need localization but does after this edit should demote to seq_annotation_done, whatever stage the payload names. That is the intent issue #275 already established — the current predicate just happens to detect it only when the client also sends the new stage.

Worth confirming as part of that work: a flags-only PATCH would then change processing_stage without the client asking, which callers should expect.

Found by review of #352; not a regression (the same gap existed before it, via the existing == SEQ_ANNOTATION_DONE form of the guard).

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with is_fp_promotion and the localization guard in sequence_annotations.py, then trace the missed-smoke PATCH from frontend/src/pages/LocalizeAlertPage.tsx. Reproduce the flags-only update described in the issue and verify that a lane newly needing localization is demoted from annotated to seq_annotation_done, avoiding the zero-box localization and export states.

Written by the indexing model from the issue text.

Assessment

Tech stack
python, typescript
Domain
api, backend, frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
55/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.