Update exporter for importing data into to Antenna #82
Draft
mihow wants to merge 8 commits into
Draft
Conversation
6 tasks
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.
Summary
This PR teaches the AMI Data Companion to export its locally-processed results in the format Antenna ingests, so a project that was processed offline can be loaded into the web platform. ADC can process local images much faster than triggering processing from Antenna, and this is the bridge that gets that work back online. The matching import side is RolnickLab/antenna#916, which feeds the exported file through the same
save_resultspath Antenna uses for live processing.The export produces one or more
PipelineResultsResponseJSON files — the same schema Antenna's processing services return — built from the occurrences already stored in the local ADC database. Large runs are split into batches so each file stays a manageable size, and crop images can optionally be collected alongside the JSON.How to use
PIPELINE_SLUGis the pipeline reference as registered in Antenna.*_batch_001.json,*_batch_002.json, … each a completePipelineResultsResponse.python manage.py import_pipeline_results <file> --project <id> --create-new-algorithms(see the paired PR).List of Changes
export api-occurrencescommand produces Antenna-importable results.trapdata/cli/export.py: newapi_occurrencescommand; converts stored occurrences toPipelineResultsResponseand writes batched JSON.DeploymentReferenceschema;deploymentadded toSourceImageandSourceImageResponse;deploymentsadded toPipelineResultsResponse.trapdata/api/export_utils.pywith converters fromDetectedObject/ occurrence dicts toDetectionResponse/ClassificationResponse/PipelineResultsResponse._export_batched_pipeline_responsesbatches by source-image count (--images-per-batch) or detection count, naming files*_batch_NNN.json.--collect-imagescopies crop images into a<name>_images/folder and rewritescrop_image_urlto point at them.capturesexport can run across all sessions, not just one date.capturescommand'sdateargument is now optional; without it, all monitoring sessions are exported.Status / TODO
This is a work in progress. Before merge:
logits=[]and features are not exported).--include-category-mapscurrently raisesNotImplementedError).Follow-ups and Discussion
These come out of reviewing the export against what the Antenna importer needs.
Occurrence/track associations are flattened away.
convert_occurrence_to_detection_responseswalks each occurrence'sexamplesand emits independentDetectionResponses with no occurrence/track id. Antenna's model supports multi-detection occurrences (tracks) viaDetection.occurrence, and the goal is to import them — but that needs the export to keep the occurrence id on each detection. Proposed: add an optionalsequence_id/track_idtoDetectionResponse(a pure grouping key) set from the ADC occurrence id, and have Antenna group by it on import. Without this, every imported detection becomes its own single-detection occurrence.Algorithm
keyderivation does not match Antenna's.create_algorithm_referencefalls back toname.lower().replace(" ", "_").replace("-", "_"), while Antenna derives keys withslugify(name). Divergent keys for the same model produce duplicate or unmatched algorithm records on import — the exact near-duplicate problem the Antenna side is trying to avoid. Align ADC's key derivation with Antenna'sslugify(and, longer term, a stablekey + versionidentity).Category maps block classifier imports. Antenna requires a category map to register a classification algorithm; with
--create-new-algorithms, importing a classifier whose results carry no category map raisesPipelineNotConfiguredon the Antenna side. Implementing--include-category-maps(TODO above) is therefore a prerequisite for importing classifier results into a fresh instance, not just a nice-to-have.Deployment payload shape. Antenna#916 expects
DeploymentResponse {id?, name, key?}onSourceImageResponse.deployment; this PR sendsDeploymentReference {name, key}. The fields line up (Antenna'sidis optional), but the top-levelPipelineResultsResponse.deploymentslist is declared and never populated here — only per-source-image deployments are set. Confirm the import path reads the per-image deployment (it does) or populate the top-level list too, and pin the contract so the two schemas do not drift.Smaller cleanups.
MockDetectedObjectis defined inside the per-example loop inconvert_occurrence_to_detection_responses(hoist it or use a dataclass); thecapturesexport still hardcodeslimit=100per event, which silently truncates a full export.