Skip to content

Add split_track + join_tracks operators and BEV edit-controls bar - #1

Open
roboav8r wants to merge 2 commits into
mainfrom
split-and-merge-tracks
Open

Add split_track + join_tracks operators and BEV edit-controls bar#1
roboav8r wants to merge 2 commits into
mainfrom
split-and-merge-tracks

Conversation

@roboav8r

Copy link
Copy Markdown
Owner

Summary

  • Two new operators for manual track corrections on grouped tracking datasets: split_track splits a track at a chosen frame (< F keeps original fo.Instance, >= F gets a fresh one); join_tracks merges N tracks onto the earliest-frame instance. Both write into a configurable target_field (default detections_corrected), auto-cloned from the source via clone_sample_field on first edit. Mutations iterate per group slice (lidar + cameras) so instance._id stays consistent across slices; all instance filters use the Mongo dict form (F("nested.array.field") == oid doesn't reliably elemMatch the array path).
  • BEV panel reorganized into two flex bars around the chart: top inspection bar (scene / View field dropdown / Coord / track counts / Preview camera) and a new edit-controls bar (View patches / Edit field / Split / Merge) between chart and scrubber. After a successful edit, the view field auto-flips to the just-written target and the chart re-renders against the new data.
  • Misc panel hardening: always use ctx.dataset (fixes PatchesView has no groups crash on filtered grid states); coerce fos.selectedSamples to a plain Set across FO versions; cameraMirrorSlice defaults to null instead of the KITTI-specific `"image_02"`.
  • `_dev_upload.py`: thin `fom.upload_plugin` wrapper that loads `deployments/.env` via `scripts/_lib/env.py` before importing `fiftyone`.

Test plan

  • `node --check dist/index.umd.js` + Python `ast.parse` clean.
  • Uploaded to `john-dev` via `_dev_upload.py`; server echoes `split_track` + `join_tracks` in the operators list.
  • Split within an instance's frame range → cross-slice consistent reassignment; chart re-renders with two tracks.
  • Split outside range → `{noop: true, instance_frame_range}`; panel logs a clear warning, no spurious selection change.
  • Merge 4 tracks → 85 detections reassigned across 83 samples onto the earliest-frame winner.
  • Panel opens cleanly with a `PatchesView` active in the grid.
  • Operator-palette form path: fire `split_track` from the menu with grid samples selected; verify the `split_frame` prompt and that the operator runs against the selection.

🤖 Generated with Claude Code

roboav8r and others added 2 commits May 23, 2026 01:28
split_track splits a single track at a chosen frame (frames < F keep
the original instance; frames >= F get a fresh fo.Instance);
join_tracks merges N tracks onto the earliest-frame instance. Both
write into a configurable target field (default detections_corrected),
auto-cloned from the source via clone_sample_field on first edit, so
edits are non-destructive. Mutations iterate per group slice (lidar +
cameras) so instance._id stays consistent across slices; all instance
filters use the Mongo dict form ({path: {"$in": [oid]}}) because
F("nested.array.field") == oid does not reliably elemMatch the
detections.detections.instance._id array path.

BEV panel reorganized into two flex bars sandwiching the chart:
- Top inspection bar: scene / View field (Detections-typed dropdown,
  populated from list_tracking_scenes) / Coord (renamed from "View") /
  track counts / Preview camera.
- New edit-controls bar between chart and scrubber: View patches /
  Edit field (text, default detections_corrected) / Split track /
  Merge tracks.
After a successful Split/Merge the panel evicts the cached payload
for (scene, target_field), explicitly re-fires get_scene_track_payload,
flips the view field to the just-written target so the chart re-renders
against the edited data, and refreshes the View-field dropdown.

split_track requires split_frame so palette / grid / lasso invocations
surface a prompt. Both operators return per_slice diagnostics
(n_scene / n_after_inst_filter / n_after_extra_filter / n_det_changed /
n_samp_touched) and split_track returns instance_frame_range so the
panel can surface a clear no-op message when the chosen frame lies
outside the instance's range.

Misc panel hardening: always use ctx.dataset in ListTrackingScenes
(PatchesView has no group_slices, was crashing on filtered grid
states); coerce fos.selectedSamples to a plain JS Set across FO
versions; defensively try/catch the setSelectedSamples write;
cameraMirrorSlice defaults to null instead of the KITTI-specific
"image_02".

_dev_upload.py is a thin fom.upload_plugin wrapper that loads
deployments/<name>.env via scripts/_lib/env.py (so FIFTYONE_API_URI /
FIFTYONE_API_KEY resolve to the right deployment before importing
fiftyone).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Prefill scene_name and instance_ids from selected patches, labels, or
samples, in that priority. Handles PatchesView (where ctx.selected
holds patch ids, not sample ids, so dataset.select silently no-ops).
Surface detection-fields and selection frame range in field descriptions.

Co-Authored-By: Claude Opus 4.7 (1M context) <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