Skip to content

Prototype: shared-observation rule for two-phase, fast3d, trackcorr - #38

Closed
alexlib wants to merge 4 commits into
mainfrom
prototype/shared-observation
Closed

alexlib wants to merge 4 commits into
mainfrom
prototype/shared-observation

Conversation

@alexlib

@alexlib alexlib commented Sep 22, 2026

Copy link
Copy Markdown
Owner

Occlusion lesson: during an occlusion tracks may hold the same point, but each track's speed comes only from its own points.

NOTE: this branch builds on e722951 plus the uncommitted two-phase refactor work (previously dirty in the working tree, now included here) -- the two_phase_tracking.py diff contains that base work on top of which the prototype sits.

What

  • Two-Phase (\plugins/two_phase_tracking.py): \�llow_shared/\max_shared/\share_tol/\max_group_size\ (config + YAML wiring under \ rack:), double-claim in contested groups, velocity never updated from shared points, tid-annotated chains (
    eturn_chains), giant-component Hungarian cap (production density percolates).
  • Fast3D (\�lgorithms/track_kernels_track3d.py, Level 1 only): contested + mutually-well-predicted edges recorded, not stolen; caller-allocated shared output arrays; cold levels never share. Trailing optional params -- old callers unaffected.
  • trackcorr path (new \ racking_shared.py, pure Python on linkage files -- kernel untouched): \mark_shared_observations\ + \�ssemble_with_shared.
  • Validation: \scripts/proto_shared_validate.py\ (synthetic crossings with ground truth: 0 switches) and \proto_long_validate.py\ (50 real frames vs res_orig linkages).
  • Docs: \docs/trackers.md\ (all eight engines, caveats, MyPTV/proPTV credits as plugins-not-forks) + \docs/two-phase-tracking.md\ (usage + parameters), linked from index.

Measured (synthetic 6-particle crossings + N=80 stress)

  • Two-Phase sharing: occlusion covered, 0 switches; ungated sharing hijacked strangers -> fixed by mutual-prediction gate (\share_tol).
  • N=80 switches 23 -> 14, missing 124 -> 68 across the prototype stack; clean minigame perfect (5 tracks, 0 missing).
  • 50 real frames: Two-Phase ~5s, matches res_orig on count/length/coverage; all 60 related unit tests pass.

Flags

All prototype flags default off. 4BE untouched. Per-tracker owners review per tracker before any Cython conversion.

alexlib and others added 4 commits September 20, 2026 00:43
…wrappers

Identical Cython kernels were copy-pasted across track_kernels_* modules.
Consolidate them in the two modules that already have .pxd files:
- pixel: _multimed_r_nlay_1layer, _point_to_pixel_out, _pixel_to_metric_out,
  _dist_to_flat_out, _candsearch_in_pix_rest_nogil,
  _sorted_candidates_fast_out_nogil, candsearch_in_pix_fast_nogil
- position: _ray_tracing_out, _angle_acc_out, _point_position_out,
  assess_new_position_fast_nogil
Other modules cimport them (pure-Python fallback imports unchanged).

Also:
- delete the track_kernels_tracking.py re-export shim; repoint setup.py,
  the cibuildwheel smoke test and the coverage tests
- delete 16 kernel wrappers with no non-test callers, with their tests

Status: hot-path tests passed after the dedup + shim removal. The wrapper
deletions have NOT been rebuilt or tested yet, and the full suite and the
pure-Python fallback check are still outstanding. See
docs/plans/2026-09-20-tracking-kernels-dedup.md for next steps.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Rebuilt clean; hot-path 49 passed, full suite 2017 passed, interpreted
kernel coverage tests 266 passed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Occlusion lesson: during an occlusion tracks may hold the same point, but each track's speed comes only from its own points.

- two_phase_tracking.py: allow_shared/max_shared/share_tol/max_group_size (config + YAML wiring), double-claim in contested groups, velocity never updated from shared points, tid-annotated chains, giant-component Hungarian cap.

- track_kernels_track3d.py (Level 1 only): contested + mutually-well-predicted edges recorded, not stolen; caller-allocated shared output arrays; cold levels never share.

- tracking_shared.py (new): linkage-level mark_shared_observations + assemble_with_shared for the trackcorr path (kernel untouched).

- scripts/proto_shared_validate.py, scripts/proto_long_validate.py: synthetic + 50-frame real-data harness.

- docs/trackers.md (all eight engines, caveats, MyPTV/proPTV credits), docs/two-phase-tracking.md (usage + parameters), index links.

All prototype flags default off. Related unit tests (60, incl. gap-relink) pass.
Copilot AI lite review requested due to automatic review settings September 22, 2026 11:08

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Unresolved compatibility and shared-observation correctness issues remain.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 1 High severity · 4 Medium severity · 2 Low severity

Open (7)
What changed in this PR

This PR prototypes shared-observation tracking across multiple trackers and refactors tracking kernels.

Changes:

  • Adds sharing support to Two-Phase, Fast3D, and trackcorr.
  • Deduplicates Cython kernels and updates tests/build configuration.
  • Adds validation scripts and tracker documentation.
File Summary
tests/​unit/​test_track_kernels_transform_coverage.py Updates transform-kernel coverage
tests/​unit/​test_track_kernels_tracking_coverage.py Updates tracking-kernel coverage
tests/​unit/​test_track_kernels_search_coverage.py Updates search-kernel coverage
tests/​unit/​test_track_kernels_geom_coverage.py Updates geometry-kernel coverage
tests/​unit/​test_track_kernels_coverage.py Updates public-kernel checks
tests/​unit/​test_track_kernels_batch_coverage.py Updates batch-kernel coverage
src/​openptv2/​tracking_shared.py Adds shared linkage utilities
src/​openptv2/​plugins/​two_phase_tracking.py Adds predictive matching and sharing
src/​openptv2/​algorithms/​track_kernels.py Updates kernel re-exports
src/​openptv2/​algorithms/​track_kernels_transform.py Deduplicates transform kernels
src/​openptv2/​algorithms/​track_kernels_tracking.py Removes compatibility shim
src/​openptv2/​algorithms/​track_kernels_track3d.py Adds shared-edge recording
src/​openptv2/​algorithms/​track_kernels_search.py Deduplicates search kernels
src/​openptv2/​algorithms/​track_kernels_position.py Adds position kernels
src/​openptv2/​algorithms/​track_kernels_position.pxd Adds position declarations
src/​openptv2/​algorithms/​track_kernels_pixel.py Updates pixel kernels
src/​openptv2/​algorithms/​track_kernels_pixel.pxd Adds pixel declarations
src/​openptv2/​algorithms/​track_kernels_geom.py Deduplicates geometry kernels
src/​openptv2/​algorithms/​track_kernels_corr.py Updates correlation kernels
src/​openptv2/​algorithms/​track_kernels_batch.py Updates batch kernels
setup.py Updates the Cython module list
scripts/​proto_shared_validate.py Adds synthetic validation
scripts/​proto_long_validate.py Adds long-window validation
docs/​two-phase-tracking.md Documents Two-Phase usage
docs/​trackers.md Documents tracker behavior
docs/​plans/​2026-09-20-tracking-kernels-dedup.md Records kernel deduplication plans
docs/​index.md Adds documentation links
.github/​workflows/​cibuildwheel.yml Updates the wheel import smoke test

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread setup.py
@@ -58,7 +58,6 @@
"track_kernels_position", # 3D ray tracing + position reconstruction
"track_kernels_track3d", # stereo-3D tracking loop
"track_kernels_corr", # forward/backward tracking loops + CAS
Comment on lines +101 to +102
if r == -1 and len(holders) >= 2:
uniq += 2
self.cfg.leaf_weight,
cost_mode=cost_mode,
allow_shared=self.cfg.allow_shared,
share_tol=self.cfg.share_tol,
Comment on lines +407 to +417
if (int(ai), int(det)) in got_shared and \
tr.get("shared_streak", 0) < self.cfg.max_shared:
# Shared observation: follow the point, keep own speed.
tr["pos"] = pts1[det].copy()
tr["shared_streak"] = tr.get("shared_streak", 0) + 1
is_shared = True
else:
tr["vel"] = (pts1[det] - old_pos) / (gap * self.cfg.dt)
tr["pos"] = pts1[det].copy()
tr["shared_streak"] = 0
is_shared = False
Comment on lines +77 to +86
pi = int(prev_k[i])
if pi < 0 or k - 1 not in frames:
continue
_, _, xyz_p = frames[k - 1]
if pi >= len(xyz_p):
continue
v = xyz_k[i] - xyz_p[pi]
if np.linalg.norm(xyz_n[j] - (xyz_k[i] + v)) < tol:
claimants.append((i, float(
np.linalg.norm(xyz_n[j] - (xyz_k[i] + v)))))
Comment thread docs/trackers.md
Comment on lines +105 to +109
### Two-Phase (`two_phase`) — the hybrid
3D search lists candidates, per-camera image distances rank them, Hungarian
per connected group decides. No motion model — immune to bad guesses, but
fails once motion outruns particle spacing. Reported +74% multi-frame
trajectories over the default on a poorly-conditioned aorta dataset.
Comment on lines 287 to 290
frame_leaves: list[np.ndarray] | None = None,
project_fn=None,
return_chains: bool = False,
) -> list[tuple[int, int, int, int]]:
@alexlib

alexlib commented Sep 22, 2026

Copy link
Copy Markdown
Owner Author

Superseded by #39, which now contains everything from this prototype: the two-phase plugin and docs were already identical on both branches (shared tree) and merged cleanly; tracking_shared.py, the Fast3D Level-1 sharing hunk (with the claim-cost alloc hoisted so the disabled path is allocation-identical), and both proto validators were merged into the #39 branch (merge commit 76fce9b) and verified there (unit suite green, proto validators run, wp1/S14c/S15 numbers reproduced). Closing to keep a single review thread; nothing was dropped -- the relink-consumer wiring remains follow-up work as noted in #39.

@alexlib alexlib closed this Sep 22, 2026
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.

2 participants