Appearance-weighted tracking cost and per-particle pulsatile gates - #39
Merged
Merged
Conversation
…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.
…ates - rr cost gains opt-in app_weight term from target grey sums (0.0 = track.c parity; track.c never used brightness in tracking) - gate_scale plumbing with scaled box/gate and tight-confirmation shell; cost denominators stay unscaled so bids remain comparable - phase_scheduler: vel/acc per-particle scales with density-gated crowd veto (dense protects, sparse frees); yaml/mode/backward params - synth crossing lab (S1-S15 incl. pulsatile S14 and bright-kick S15), ensemble/vote/judge/divergence tooling, wp1 verifiers - results: wp1 98.16 percent links parity, ppar exact parity, S14c 61 to 100 percent, S15 83 to 100 percent at w>=0.1; plan addenda 1-12
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Critical output-format and ensemble reproducibility issues remain, along with tracking correctness and consistency defects.
Get a fresh assessment by requesting another Copilot review.
Review effort: Lite
Findings: 2
Open (4)
What changed in this PR
Adds opt-in appearance-weighted tracking, per-particle gate scaling, two-phase tracking utilities, kernel refactoring, validation tooling, and documentation.
Changes:
- Threads brightness and adaptive gate data through tracking kernels.
- Adds tests, benchmarks, diagnostics, and ensemble validation scripts.
- Refactors kernel modules and updates packaging and documentation.
| File | Summary |
|---|---|
tests/unit/test_two_phase_tracking.py |
Adds two-phase tracker tests. |
tests/unit/test_track_kernels_tracking_coverage.py |
Updates tracking kernel coverage. |
tests/unit/test_track_kernels_geom_coverage.py |
Adjusts geometry coverage. |
tests/unit/test_track_kernels_coverage.py |
Updates kernel coverage tests. |
tests/unit/test_track_kernels_batch_coverage.py |
Updates batch coverage tests. |
src/openptv2/tracker.py |
Exposes tracking options. |
src/openptv2/algorithms/tracking_run.py |
Stores tracking configuration. |
src/openptv2/algorithms/tracking_frame_buf.py |
Adds target brightness storage. |
src/openptv2/algorithms/track.py |
Computes appearance and gate data. |
src/openptv2/algorithms/track_kernels.py |
Updates kernel exports. |
src/openptv2/algorithms/track_kernels_tracking.py |
Removes compatibility shim. |
src/openptv2/algorithms/track_kernels_track3d.py |
Updates kernel imports. |
src/openptv2/algorithms/track_kernels_position.py |
Adds shared position kernels. |
src/openptv2/algorithms/track_kernels_position.pxd |
Declares position kernels. |
src/openptv2/algorithms/track_kernels_pixel.py |
Updates pixel kernel handling. |
src/openptv2/algorithms/track_kernels_pixel.pxd |
Declares pixel kernels. |
src/openptv2/algorithms/track_kernels_batch.py |
Removes duplicated wrappers. |
setup.py |
Updates compiled module configuration. |
scripts/vote_links.py |
Adds ensemble voting. |
scripts/verify_two_phase_wp1.py |
Adds two-phase validation. |
scripts/verify_same_trajectories.py |
Adds trajectory parity validation. |
scripts/verify_ppar_wp1.py |
Adds per-particle validation. |
scripts/verify_adaptive_wp1.py |
Adds adaptive tracking validation. |
scripts/track_triage_typesafe.py |
Adds trajectory triage. |
scripts/trace_divergence.py |
Adds divergence tracing. |
scripts/synth_dacc_rescue.py |
Adds acceleration-gate experiments. |
scripts/sweep_track_params.py |
Adds parameter sweeps. |
scripts/sweep_app_weight.py |
Adds appearance-weight sweeps. |
scripts/run_postprocess_wp1.py |
Adds validation postprocessing. |
scripts/run_dacc19.py |
Adds parity runner. |
scripts/run_cascade.py |
Adds cascade tracking. |
scripts/proto_global_resolve.py |
Adds global-resolution prototype. |
scripts/probe_search.py |
Adds candidate-search diagnostics. |
scripts/plot_hard_links.py |
Adds hard-link plotting. |
scripts/miss_profiler.py |
Adds miss profiling. |
scripts/judge_hard_links.py |
Adds hard-link adjudication. |
scripts/inspect_refusals.py |
Adds refusal inspection. |
scripts/drill_s4_global.py |
Adds global-resolution diagnostics. |
scripts/diagnose_ppar_wp1.py |
Adds adaptive regression diagnosis. |
scripts/diag_speed_ceiling.py |
Adds speed diagnostics. |
scripts/diag_position_noise.py |
Adds position-noise diagnostics. |
scripts/diag_link_displacement.py |
Adds displacement diagnostics. |
scripts/diag_inlist_probe.py |
Adds candidate-list probing. |
scripts/diag_conflict_parity.py |
Adds conflict-parity diagnostics. |
scripts/collect_ensemble_wp1.py |
Adds ensemble collection. |
scripts/check_dv_hard.py |
Adds displacement checks. |
scripts/cascade_track.py |
Adds link merging. |
scripts/bench_two_phase.py |
Adds two-phase benchmarks. |
scripts/bench_4be_crossing.py |
Adds crossing benchmarks. |
scripts/analyze_residual.py |
Adds residual analysis. |
scripts/_run_one_step.py |
Adds one-step execution helper. |
docs/two-phase-tracking.md |
Documents two-phase tracking. |
docs/trackers.md |
Documents tracker choices. |
docs/plans/2026-09-20-tracking-kernels-dedup.md |
Records kernel deduplication. |
docs/index.md |
Links tracker documentation. |
.github/workflows/cibuildwheel.yml |
Updates import smoke testing. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+31
to
+42
| for t0, r0, t1, r1 in tp_links: | ||
| if not (0 <= t0 < len(mnxt) and 0 <= t1 < len(mprev)): | ||
| continue | ||
| if not (0 <= r0 < nrows[t0] and 0 <= r1 < nrows[t1]): | ||
| continue | ||
| # Free tail: trackcorr marks "no outgoing link" as -1 (never | ||
| # claimed) or -2 (lost contest / dropped); both are linkable. | ||
| # Free head: prev == -1. Anything else is taken -- never steal. | ||
| if mnxt[t0][r0] < 0 and mprev[t1][r1] < 0: | ||
| mnxt[t0][r0] = r1 | ||
| mprev[t1][r1] = r0 | ||
| added.append((t0, r0, t1, r1)) |
Comment on lines
+56
to
+57
| lines = [f"{len(R[f])}"] | ||
| n = min(len(R[f]), *(len(P[x][f]) for x in names)) |
Comment on lines
+6
to
+7
| Run from repo root (detached): | ||
| uv run python -u scripts/verify_adaptive_wp1.py |
Comment on lines
+1201
to
+1204
| int(getattr(run_info, "loser_retry", 1)), | ||
| int(getattr(run_info, "cold_start_neighbour", 1)), | ||
| float(getattr(run_info, "app_weight", 0.0)), | ||
| gate_scale, |
Absorb the shared-observation prototype: tracking_shared.py (trackcorr linkage-level sharing, pure Python), Fast3D Level-1 contested-edge recording, and both proto validators. The two-phase plugin and docs are identical on both branches (shared working tree) and merge cleanly.
…ernel args - track3d Level-1 sharing: allocate claim_cost_2 and record claim costs only when use_share is on; the disabled path keeps its exact original allocation profile. - test_track_kernels_tracking_coverage: pass targ_sumg_1/2 + cand_app_2 to trackcorr_loop_fast (required since appearance/gate_scale plumbing); gate_scale keeps its None default.
…ython) - _grid_build/_grid_candsearch in track_kernels_pixel (nogil) + branch in _sorted_candidates; per-step build for frame-2/3 targets in trackcorr_loop_fast; threaded via TrackingRun/Tracker (default off). - Grid finds the true in-window set; legacy y-band scan assumes y-sorted targets (wp1 targets are not sorted) and silently misses candidates. - wp1 neutrality: 7238/97.98pc exact with flag on. No speedup on wp1 -- the scan is not the bottleneck (projections/ray-tracing dominate); kept as correctness hardening, default off.
- TwoPhaseTrackerConfig gains bidirectional: bool (default False) and bwd_v_max: float | None (optional wider backward search). - Forward-First bidirectional merge: preserves 100% of forward links, adding backward links greedily by 3D distance only where both endpoints are unlinked (strict 1-to-1 matching, never steals from forward). - Two-hop confirmation: confirm_tol / confirm_ends flags. - Increases wp1 exact link recall from 96.26% to 97.48% (7201 links, closing 75% of gap to 4-frame trackcorr) while running in only 3.0s (5x faster). - S1-S14c test suite 100% passed.
…uto-promote to grid search if unsorted - target_recognition() and _detect_single_worker() now explicitly sort detected targets by y (monotonically non-decreasing) before writing/returning. This preserves the 3dptv pipeline invariant required by stereo correspondence and trackcorr's binary search. - trackcorr_c_loop checks if targets in Frame 2 or 3 are strictly y-sorted; if not, it auto-promotes to use_grid=1 to guarantee zero missed candidates.
…get_recognition Replaces manual array indexing with the canonical TargetArray.sort_y() method, ensuring all callers of target_recognition() receive a y-sorted target list without touching the underlying C/Cython segmentation.
- pyproject.toml: add E741, F401, F841 to per-file-ignores for scripts/** matching tests/** policy (benchmark and diagnostic scripts mirror legacy C matrix names). - Format import blocks and clean up unused imports in scripts and unit tests. - ruff check . now passes with 0 errors.
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.


What this adds
r += app_weight*|d|/(sum)\ at all four cost sites. \�pp_weight=0.0\ (default) is bit-identical to 3dptv \ rack.c\ behaviour, which never used brightness in tracking (verified against source).
Measured results (merged tree)
Notes