Multi-target tracking over gri per-target estimators: ingest/routing, measurement-space scoring, GNN + MFA/MHT association, track lifecycle, LMB existence, and Poisson-binomial cardinality
Project description
gri-multitrack
Multi-target geolocation tracking. gri-multitrack combines the gri per-target
Kalman-IMM (gri-kalman, fed by gri-obs observables) with a multi-target policy
layer: ingest/routing of the feed-in data tiers, measurement-space scoring,
per-scan association, track lifecycle, existence (Labeled Multi-Bernoulli), and
a Poisson-binomial count distribution.
The governing seam is "gri scores, gri-multitrack assigns": gri-kalman owns
per-target estimation and the measurement-space likelihoods; gri-multitrack owns
everything multi-target. The multi-target layer is DIY on numpy/scipy --
gri-multitrack is Stone-Soup-free (see the "Architecture pivot" in AGENTS.md).
The primary tracker class is MultiTracker (the "Crucible" name now belongs to
the companion 3D app).
See AGENTS.md (rationale), PLAN.md (build order / status), and MULTITRACK.md
(detailed item spec) for the design record. SIM.md specs crucible_sim, a
standalone scenario / test-data generator (sibling repo ~/work/collab/crucible_sim/)
that emits the truth / input / output JSONL fixtures used to exercise gri-multitrack --
now built (all four layers, the 1a..3d scenario library, a single-target replay
harness, and a GOSPA/OSPA scorer; see its SIM.md / CLAUDE.md).
Status
This is the Phase-1 skeleton (loose coupling, GNN scaffold associator). It runs end to end: ingest -> score -> associate -> gri IMM update -> lifecycle -> LMB output, on geos, raw TDOAs, and presence events.
Implemented:
- Ingest + router for the feed-in tiers (geo
Ell, observables, presence). - Per-track adapter over any gri
Tracker(defaultSmartSegmentedIMM; CV / CoordinatedTurn / Static bank). - Measurement-space scoring seam (Gaussian innovation + chi-squared gate).
- GNN scaffold associator (local scipy Hungarian) for bring-up.
- MFA tracker (
MfaTracker): a local hypothesis-oriented MHT that defers at ambiguous crossings and resolves via accumulated kinematic likelihood -- the v1 associator (loose-coupled; not Stone Soup's MFA). Standalone engine mirroringgri-multitrack. - Track lifecycle: birth from geos, M-of-N confirm, patient deletion.
- Existence r_i + Poisson-binomial count distribution.
- Presence ("is it on") ->
coast(t)+ existence bump. - LMB output: labeled tracks + count distribution + per-track
predictedhorizons + the per-scanassociationdiagnostic (gates / marginals / hypotheses), associator-agnostic.
Not yet (Phase 3 -- see PLAN.md):
- Stationary handoff to
cluster_convolve, split/merge, batch RTS orchestration. - JSONL serialization, DIY GOSPA/OSPA metrics, and
crucible_vizplotting.
Notable design choices
- The per-track estimator is any gri-kalman
Tracker; the default isSmartSegmentedIMM. gri-kalman exposes one uniform interface (update(ell, t)/update_observable/predict/coast/smoothed_track/result/is_initialized) acrossIMM,SmartIMM,SegmentedIMM, andSmartSegmentedIMM. gri-multitrack defaults to the maneuver-segmenting, outlier-rejectingSmartSegmentedIMMthe design calls for; passtracker_factory=make_imm(or anyTrackerfactory) to swap it. The choice is isolated togri_multitrack/track.py. - Stone-Soup-free; multi-target is DIY on numpy/scipy. Both associators are
local (GNN over scipy
linear_sum_assignment; MFA a local hypothesis-oriented MHT). Stone Soup's MFA is filter-coupled and would cost the gri IMM, and is heavy (~48 MB of deps +ortools); see theCLAUDE.md"Architecture pivot". If LAP speed ever matters, addlapsolver/lap(tiny) -- notortools. Stone Soup remains only as an optional dev-time GOSPA/OSPA cross-check.
Install
Uses uv with editable path dependencies on the sibling gri repos (in
../../foss/).
uv sync # core (Stone-Soup-free)
uv sync --extra crosscheck # optional: Stone Soup, for a dev-time GOSPA/OSPA check only
Run
uv run python examples/two_target_demo.py # end-to-end demo
uv run pytest # tests
uv run ruff check gri_multitrack test # lint
uv run ty check # type check
Quick use
from gri_multitrack import gri-multitrack
tracker = MultiTracker()
# each item is (payload, time_s); payload is an Ell, a gri-obs observable,
# or a PresenceObs.
outputs = tracker.process([(ell0, 0.0), (tdoa1, 1.0), (presence, 2.0)])
final = outputs[-1]
for t in final.tracks:
print(t.label, t.existence, t.is_stationary, t.mode_probabilities)
print(final.count_distribution) # Poisson-binomial P(N=k)
Layout
gri_multitrack/ingest.py-- feed-in types, routing, scan grouping.gri_multitrack/track.py-- per-track adapter over the gri IMM.gri_multitrack/scoring.py-- measurement-space likelihood + gate ("gri scores").gri_multitrack/association.py-- GNN scaffold +Associatorprotocol.gri_multitrack/lifecycle.py-- birth / confirm / delete / existence.gri_multitrack/cardinality.py-- Poisson-binomial count distribution.gri_multitrack/output.py-- Labeled Multi-Bernoulli output records.gri_multitrack/tracker.py-- thegri-multitrackorchestrator.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gri_multitrack-0.1.0.tar.gz.
File metadata
- Download URL: gri_multitrack-0.1.0.tar.gz
- Upload date:
- Size: 152.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
aab694cd849670a1c536db04610124a1dd34c8822e103204d397e365fa61306d
|
|
| MD5 |
fe69e93546aca2f1400cd74a976cad95
|
|
| BLAKE2b-256 |
8e55a48e68efb0b29b04b7e4793a1dae57e1ea501853cd4a36e06b86167612d6
|
File details
Details for the file gri_multitrack-0.1.0-py3-none-any.whl.
File metadata
- Download URL: gri_multitrack-0.1.0-py3-none-any.whl
- Upload date:
- Size: 32.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eb06ac09cbe0fb4e2aa79176ca68f89027132962ae277074b620bd0878c44ff2
|
|
| MD5 |
4a7153753b4d9963a69b102a91a16c89
|
|
| BLAKE2b-256 |
ca382695398dbad3f44cf14057a392035a2065e4374e402332e115df5d2bd5c5
|