Library Architecture
Overview
The Tracker Component Library contains 153 modules organized into 8 major subsystems:
Dynamic Estimation (15 modules) - Filtering and state estimation
Data Association (8 modules) - Assignment and correlation algorithms
Coordinate Systems (20 modules) - Conversions and transformations
Dynamic Models (12 modules) - Motion models and process noise
Navigation (18 modules) - INS, guidance, geodesy
Geophysical (15 modules) - Gravity, magnetism, weather, terrain
Tracking (12 modules) - Multi-target tracking and containers
Mathematical (25 modules) - Special functions, distributions, integration
High-Level Subsystem View
pytcl/
├── core/ # Utility: types, decorators, constants
├── containers/ # Data structures: TrackSet, EstimationSet
│
├── dynamic_estimation/ # Filtering engines
│ ├── kalman/ # KF, EKF, UKF, CKF, IMM
│ ├── particle_filters/ # PF, SISR, SIR
│ ├── batch_estimation/ # Least squares, smoothing
│ └── measurement_update/ # Update equations
│
├── dynamic_models/ # Motion models
│ ├── continuous_time/ # White noise acc, Gauss-Markov
│ ├── discrete_time/ # CT to DT conversions
│ └── process_noise/ # Q matrix generation
│
├── assignment_algorithms/ # Data association
│ ├── two_dimensional/ # 2D assignment
│ ├── three_dimensional/ # 3D/MHT assignment
│ └── optimization/ # Hungarian, auction, Murty
│
├── trackers/ # Tracker implementations
│ └── multi_tracker_gnn/ # GNN tracker
│
├── coordinate_systems/ # Coordinate transformations
│ ├── conversions/ # Cart↔spherical, geodetic, etc
│ ├── rotations/ # Euler angles, quaternions, DCM
│ ├── jacobians/ # Partial derivatives
│ └── projections/ # Map projections (UTM, Mercator)
│
├── navigation/ # Navigation
│ ├── geodesy/ # Great circle, rhumb line
│ ├── ins_gnss/ # INS mechanization
│ ├── ephemerides/ # JPL ephemerides
│ └── tdoa/ # Time difference of arrival
│
├── geophysical/ # Environmental models
│ ├── gravity/ # WGS84, EGM96/2008
│ ├── magnetism/ # WMM, IGRF
│ ├── atmosphere/ # NRLMSISE00
│ └── terrain/ # Terrain elevation
│
├── astronomical/ # Orbital mechanics
│ ├── orbital_mechanics/ # Keplerian propagation
│ ├── lambert/ # Lambert's problem
│ ├── reference_frames/ # ECEF↔ECI, precession, nutation
│ ├── relativity/ # Relativistic corrections
│ ├── sgp4/ # SGP4 propagator
│ └── ephemeris/ # Ephemeris functions
│
├── mathematical_functions/ # Math utilities
│ ├── special_functions/ # Marcum Q, Lambert W, Bessel
│ ├── distributions/ # Probability distributions
│ ├── statistics/ # Statistical functions
│ ├── numerical/ # Integration, interpolation
│ └── optimization/ # Minimization, root finding
│
├── signal_processing/ # Signal processing
│ ├── filtering/ # IIR, FIR filters
│ ├── detection/ # CFAR, matched filtering
│ └── transforms/ # FFT, wavelets
│
├── clustering/ # Pattern recognition
│ └── algorithms/ # K-means, DBSCAN, hierarchical
│
├── performance_evaluation/ # Metrics and analysis
│ ├── metrics/ # NEES, NIS, Cramer-Rao
│ ├── consistency/ # Filter consistency checks
│ └── benchmarking/ # Performance profiling
│
├── gpu/ # GPU acceleration
│ ├── cupy_backend/ # NVIDIA acceleration
│ └── mlx_backend/ # Apple Silicon acceleration
│
└── plotting/ # Visualization
Subsystem Details
Dynamic Estimation Subsystem
Purpose: Implement state estimation algorithms (filtering).
When to use: Any system where you need to estimate hidden state from noisy measurements.
Modules:
kalman- Linear/nonlinear Kalman variants (KF, EKF, UKF, CKF)particle_filters- Nonlinear, non-Gaussian filteringbatch_estimation- Offline smoothing and batch processingmeasurement_update- Generic update equations
Quick Example:
import numpy as np
from pytcl.dynamic_estimation.kalman import KalmanFilter
from pytcl.dynamic_models import f_constant_velocity, q_constant_velocity
# Setup filter
T = 0.1 # time step
x = np.array([0, 1, 0, 0]) # state: pos, vel (2D)
P = np.eye(4) * 0.1
F = f_constant_velocity(T, num_dims=2)
Q = q_constant_velocity(T, sigma_a=0.1, num_dims=2)
H = np.eye(2, 4) # observe position
R = np.eye(2) * 0.5
kf = KalmanFilter(F, H, Q, R)
# Predict and update
measurements = [np.array([1.1, 0.5]), np.array([2.3, 1.2]), ...]
for z in measurements:
x, P = kf.predict(x, P)
x, P = kf.update(x, P, z)
- Dependency Graph:
Requires:
dynamic_models(F, Q matrices)Requires:
coordinate_systems(if fusing different coordinate types)Optional:
performance_evaluation(diagnostic metrics)
Data Association Subsystem
Purpose: Match observations (measurements) to tracks (targets).
When to use: Multi-target tracking with multiple sensors or measurement ambiguity.
Modules:
two_dimensional- 2D assignment (gating, MHT)three_dimensional- 3D assignment, Murty algorithmoptimization- Hungarian, auction algorithms
Quick Example:
from pytcl.assignment.optimization import assignment_nd
from scipy.spatial.distance import cdist
# Compute cost matrix (lower = better match)
positions = np.array([[0, 0], [1, 1], [2, 2]]) # 3 targets
measurements = np.array([[0.1, 0.1], [2.1, 2.1]]) # 2 measurements
cost = cdist(positions[:, :2], measurements, metric='euclidean')
cost[cost > 0.5] = np.inf # gate: only close matches
# Solve assignment
assignments = assignment_nd(cost) # [(target_i, meas_j), ...]
- Dependency Graph:
Requires: Computed cost matrix (usually from coordinate_systems)
Optional:
clustering(pre-grouping tracks)
Coordinate Systems Subsystem
Purpose: Transform between different coordinate representations and reference frames.
When to use: Working with data from different sensors or coordinate systems.
Modules:
conversions- Spherical ↔ Cartesian, geodetic, RUV, ENUrotations- Euler angles, quaternions, rotation matrices (DCM)jacobians- Partial derivatives for Jacobian matricesprojections- Map projections (UTM, Mercator, Lambert Conformal)
Quick Example:
from pytcl.coordinate_systems.conversions import sphere2cart, cart2sphere
from pytcl.coordinate_systems.rotations import euler2dcm
# Spherical to Cartesian
spherical = np.array([1.0, np.pi/4, np.pi/6]) # range, az, el
cartesian = sphere2cart(spherical)
# Rotation
euler = np.array([0, 0, np.pi/4]) # heading, pitch, roll
DCM = euler2dcm(euler)
- Dependency Graph:
Depends on:
mathematical_functions(for special functions)Used by: Virtually all other subsystems
Provides: Jacobians for
dynamic_estimation
Geophysical Subsystem
Purpose: Model environmental factors (gravity, magnetic field, atmosphere, terrain).
When to use: Accurate modeling of forces on vehicles, environmental corrections.
Modules:
gravity- WGS84 ellipsoid, EGM96/2008 geoid, gravity anomaliesmagnetism- World Magnetic Model (WMM), IGRFatmosphere- NRLMSISE-00 model for density, temperatureterrain- Terrain elevation from digital elevation models
Quick Example:
from pytcl.gravity.gravity_models import gravity_force
from pytcl.magnetism.magnetic_models import magnetic_field
from pytcl.atmosphere.nrlmsise00 import atmospheric_density
# Compute gravitational acceleration
ecef_pos = np.array([6378000, 0, 0]) # Earth surface
g_accel = gravity_force(ecef_pos) # m/s^2
# Magnetic field
mag_field = magnetic_field(ecef_pos) # nT
# Atmospheric density
lat, lon, alt = 40.0, -74.0, 35000 # 35,000 feet
rho = atmospheric_density(lat, lon, alt)
- Dependency Graph:
Depends on:
coordinate_systems,mathematical_functionsUsed by:
navigation,astronomical(for satellite propagation)
Astronomical Subsystem
Purpose: Orbital mechanics, ephemerides, and celestial reference frames.
When to use: Satellite operations, space vehicle navigation, astronomical calculations.
Modules:
orbital_mechanics- Keplerian propagation, anomaly conversionslambert- Lambert’s problem (bi-elliptic solutions)reference_frames- ECEF↔ECI, precession, nutation, polar motionrelativity- Relativistic corrections (Schwarzschild, Shapiro delay)sgp4- SGP4 propagator with perturbationsephemeris- JPL ephemeris interface
Quick Example:
from pytcl.astronomical.orbital_mechanics import propagate_kepler
from pytcl.astronomical.reference_frames import ecef2eci, eci2ecef
# Keplerian propagation
semimajor_axis = 6800e3 # meters
eccentricity = 0.001
inclination = 98.0 # degrees (sun-synchronous)
state = np.array([semimajor_axis, eccentricity, inclination,
0, 0, 0]) # Keplerian elements
# Propagate 1 hour
state_prop = propagate_kepler(state, t=3600)
- Dependency Graph:
Depends on:
coordinate_systems,navigation,geophysicalUsed by: Satellite tracking systems
Provides: Ephemeris data to navigation systems
Mathematical Functions Subsystem
Purpose: Special functions, probability distributions, numerical methods.
When to use: Implementing advanced algorithms (Bessel functions, special distributions).
Modules:
special_functions- Marcum Q, Lambert W, Bessel, hypergeometricdistributions- Rayleigh, Rician, non-central chi-squarestatistics- Statistical tests, confidence intervalsnumerical- Integration, interpolation, root findingoptimization- Minimization, root solving
Quick Example:
from pytcl.mathematical_functions.special_functions import (
marcum_q, lambert_w
)
from pytcl.mathematical_functions.distributions import (
rician_pdf, rayleigh_pdf
)
# Marcum Q function (detection probability)
a, b = 2.0, 3.0
q_val = marcum_q(a, b) # Detection probability
# Rician distribution (fading signals)
signal = 1.0
noise = 0.5
x = 2.0
pdf_val = rician_pdf(x, signal, noise)
- Dependency Graph:
Depends on: NumPy, SciPy (foundation)
Used by: Nearly all other subsystems
Tracking Subsystem
Purpose: Multi-target tracking implementations and related containers.
When to use: Building complete tracking systems from filters and association.
Modules:
multi_tracker_gnn- Global Nearest Neighbor trackercontainers- TrackSet, EstimationSet data structuresclustering- Track clustering algorithms
Quick Example:
from pytcl.trackers.multi_tracker_gnn import GNNTracker
from pytcl.containers import TrackSet, Track
# Create tracker
tracker = GNNTracker(
gate_threshold=5.0,
new_track_threshold=3,
delete_threshold=5
)
# Process measurements
for measurements in measurement_stream:
tracks = tracker.update(measurements)
- Dependency Graph:
Depends on:
dynamic_estimation,assignment_algorithms,coordinate_systemsUsed by: Complete tracking applications
Common Architecture Patterns
Pattern 1: Single-Target Tracking
Use Case: Tracking one object with one or more sensors.
Workflow:
# 1. Get measurements
measurements = sensor.get_observations()
# 2. Convert to common frame
from pytcl.coordinate_systems import sphere2cart
cartesian_meas = sphere2cart(measurements)
# 3. Filter update
from pytcl.dynamic_estimation.kalman import kf_predict, kf_update
x_pred, P_pred = kf_predict(x, P, F, Q)
x_upd, P_upd = kf_update(x_pred, P_pred, cartesian_meas, H, R)
- Modules Used:
dynamic_estimation: Filterdynamic_models: Motion model (F, Q)coordinate_systems: Measurement conversion
Pattern 2: Multi-Target Tracking with Assignment
Use Case: Tracking multiple targets with data association.
Workflow:
# 1. Predict all tracks
for track in tracks:
track.x_pred, track.P_pred = kf_predict(track.x, track.P, F, Q)
# 2. Compute assignment cost
from scipy.spatial.distance import cdist
positions = np.array([t.x_pred[:2] for t in tracks])
measurements = get_measurements()
cost = cdist(positions, measurements)
cost[cost > gate_dist] = np.inf
# 3. Solve assignment
from pytcl.assignment.optimization import assignment_nd
assignments = assignment_nd(cost)
# 4. Update assigned tracks
for track_idx, meas_idx in assignments:
if meas_idx >= 0:
x_upd, P_upd = kf_update(
tracks[track_idx].x_pred,
tracks[track_idx].P_pred,
measurements[meas_idx],
H, R
)
- Modules Used:
dynamic_estimation: Filterassignment_algorithms: Data associationcoordinate_systems: Gating
Pattern 4: Satellite Propagation with Corrections
Use Case: Accurate satellite orbit prediction.
Workflow:
from pytcl.astronomical.orbital_mechanics import propagate_kepler
from pytcl.astronomical.reference_frames import ecef2eci
from pytcl.geophysical.gravity import perturbations
# 1. Initial state in ECI
state_eci = get_initial_state()
# 2. Propagate with perturbations
for t in time_steps:
# Keplerian propagation
state_eci = propagate_kepler(state_eci, dt)
# Apply perturbations
perturbations_eci = perturbations(state_eci)
state_eci += perturbations_eci * dt
# 3. Convert to ECEF for ground tracking
state_ecef = ecef2eci(state_eci)
- Modules Used:
astronomical: Orbit propagationgeophysical: Environmental effectscoordinate_systems: Frame conversions
Dependency Resolution Guide
Question: How do I find what modules I need?
Answer: Follow this decision tree:
Are you doing state estimation?
→ YES: Use
dynamic_estimationNeed motion model? → Use
dynamic_modelsNeed to convert measurements? → Use
coordinate_systems
Are you tracking multiple targets?
→ YES: Use
assignment_algorithmsNeed advanced assignment? → Use
three_dimensional
Are you working with different coordinate systems?
→ YES: Use
coordinate_systemsNeed rotations? → Use
rotationsNeed projections? → Use
projections
Are you doing navigation?
→ YES: Use
navigationNeed geodetic calculations? → Use
geodesyNeed INS/GNSS fusion? → Use
ins_gnssNeed satellite operations? → Use
astronomical
Do you need environmental modeling?
→ YES: Use
geophysicalGravity effects? → Use
gravityMagnetic field? → Use
magnetismAtmospheric? → Use
atmosphere
Module Import Patterns
Single Function Import (for specific use):
from pytcl.coordinate_systems.conversions import sphere2cart
result = sphere2cart(data)
Submodule Import (for multiple related functions):
from pytcl.dynamic_estimation import kalman
x_pred, P_pred = kalman.kf_predict(x, P, F, Q)
Top-Level Import (for convenience):
import pytcl
result = pytcl.sphere2cart(data) # If re-exported
Check available functions in module:
import pytcl.coordinate_systems.rotations as rotations
print([name for name in dir(rotations) if not name.startswith('_')])
Best Practices by Use Case
- Rapid Prototyping
→ Use top-level functions, simple examples
- Production Tracking System
→ Use
trackers.multi_tracker_gnndirectly → Add diagnostic checks fromperformance_evaluation- Research/Development
→ Use individual modules for maximum flexibility → Combine filters with custom models
- High-Performance Real-Time
→ Use GPU acceleration (
gpumodule) → Pre-compute Jacobians → Use Numba-accelerated functions → See Performance Optimization Guide- Safety-Critical Systems
→ Use consistency checks from
performance_evaluation→ Monitor NEES/NIS values → Use multiple independent filters for voting → Validate withkalman_filter_tuningdiagnostics
See Also
Kalman Filter Tuning Guide - Detailed filter parameter tuning
GPU Acceleration Guide - Using GPU computation
Performance Optimization Guide - Performance profiling and optimization
Getting Started - Getting started guide
Examples:
examples/folder with complete working code