Skip to content

Appearance-weighted tracking cost and per-particle pulsatile gates - #39

Merged
alexlib merged 16 commits into
mainfrom
refactor/dedup-tracking-kernels
Sep 22, 2026
Merged

alexlib merged 16 commits into
mainfrom
refactor/dedup-tracking-kernels

Conversation

@alexlib

@alexlib alexlib commented Sep 22, 2026

Copy link
Copy Markdown
Owner

What this adds

  • Opt-in brightness in the tracking cost: target grey sums flow through a new SoA array into the kernel;
    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).
  • Per-particle gate freedom (\gate_scale\ plumbing, no \ par\ mutation): scaled search box + base acc gate, unscaled cost denominators so bids stay comparable, scaled shell with tight confirmation.
  • Phase scheduler (\scripts/phase_scheduler.py): vel/acc per-particle scales with an automatic density-gated crowd veto (dense data protects, sparse data frees), plus \yaml/\mode/\�ackward\ params.
  • Shared-observation prototype (absorbed from Prototype: shared-observation rule for two-phase, fast3d, trackcorr #38): \ racking_shared.py\ (trackcorr linkage-level sharing, pure Python, experimental), Fast3D Level-1 contested-edge recording (default-off; claim-cost alloc hoisted so the disabled path is allocation-identical), both proto validators. The two-phase plugin and docs were already identical on both branches.
  • Includes main: PR perf: fix per-frame searchsorted overhead and thread-pool churn in correspondence matching #37 perf work (shared thread pool, C bisection) merged in.
  • Validation lab: synth crossing scenes S1-S15 (pulsatile S14, bright-kick S15), ensemble/vote/judge/divergence tooling, wp1 verifiers, two-phase unit tests (6 passed).

Measured results (merged tree)

  • Unit suite: 1743 passed, 0 failed (fewer collected than main: dedup dropped orphaned-kernel tests; coverage tests updated for the new kernel args).
  • wp1 vs 3dptv reference: 98.16% links / 93.11% chains parity, link-exact; per-particle forward exact parity; fwd+bwd identical.
  • S14c systole: 61% fixed -> 100% per-particle; S15 brightness: 83% -> 100% at w>=0.1; S11/S1 no-regression.
  • app=0.1 costs -17/-24 on natural-brightness wp1, so default stays 0.0 (opt-in).
  • Proto validators run: two-phase 0 switches, fast3d pairs recorded, 1661 shared marks on 50 real frames (assembly left experimental; relink consumer is follow-up).
  • Full methodology and per-addendum evidence: \docs/plans/2026-09-20-trackcorr-vs-3dptv-link-gap-plan.md\ (addenda 1-12).

Notes

  • Run logs (*_out.txt) and scratch outputs intentionally not committed.
  • Compiled Cython extensions rebuild via \uv run python setup.py build_ext --inplace; all features default-off and neutrality-validated.

alexlib and others added 5 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.
…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
Copilot AI lite review requested due to automatic review settings September 22, 2026 11:59

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

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 High severity · 2 Low severity

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 thread scripts/cascade_track.py
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 thread scripts/vote_links.py
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.
@alexlib
alexlib merged commit 0bfa918 into main Sep 22, 2026
15 checks passed
@alexlib
alexlib deleted the refactor/dedup-tracking-kernels branch September 22, 2026 21:34
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