Diagnostics
Opt-in logging, instrumentation, and progress reporting. pytcl is silent by default; see Diagnostics Guide for the narrative guide and the opt-in policy.
Diagnostics: opt-in logging, instrumentation, and progress reporting.
pytcl is completely silent by default: importing it disables the pytcl
loguru namespace and installs no handlers. Call enable_debug_logging()
to see gating rejections, association decisions, filter-health symptoms,
and data-file resolution at DEBUG level; disable_debug_logging()
returns to silence. This module is the redesigned successor to the
pytcl.logging_config module removed in v2.0.0; no compatibility is
provided.
Examples
>>> import pytcl
>>> pytcl.diagnostics.diagnostics_enabled()
False
- pytcl.diagnostics.diagnostics_enabled()[source]
Whether diagnostic logging is currently enabled.
Hot paths consult this before constructing log payloads, so the disabled path costs one boolean check.
- pytcl.diagnostics.enable_debug_logging(level='DEBUG')[source]
Enable pytcl’s diagnostic logging with a rich-formatted handler.
- Parameters:
level (str, optional) – Minimum level to emit (“DEBUG”, “INFO”, “WARNING”, …).
Notes
Idempotent: calling again replaces the previous handler rather than stacking a second one. Output goes to stderr, ASCII-safe.
A bad
levelraises before anything is touched: the new handler is added first, so the failure happens while state is still exactly what it was before the call (namespace disabled, or however a prior successful call last left it).loguru installs a default stderr handler (id 0) at import time; left alive, it double-prints every record next to the one pytcl’s own handler emits. This function removes it the first time diagnostics are enabled and remembers that it did so;
disable_debug_logging()then puts an equivalent handler back (logger.add(sys.stderr), loguru’s own default configuration) so the host application’s logging is not left worse off than before pytcl touched it. That replacement is loguru’s stock handler, not a byte-for-byte restoration of whatever the host had configured at id 0 – if the host had customized it, this function has no way to know and does not try to reproduce it.
- pytcl.diagnostics.disable_debug_logging()[source]
Return the library to complete silence. Idempotent.
If
enable_debug_logging()removed loguru’s default stderr handler to prevent double-printing, this restores an equivalent one (see that function’s docstring for the exact caveat).
- pytcl.diagnostics.track_table(tracks, console=None)[source]
Render a summary table of tracks to the console.
- Parameters:
tracks (sequence) – Track objects with
id,status,state(and optionallycovariance) attributes, e.g. fromMultiTargetTracker.process.console (rich.console.Console, optional) – Target console; defaults to stderr. Output is ASCII-only (
box.ASCII) to satisfy the console-encoding contract.
- pytcl.diagnostics.progress_bar(iterable, description='working', total=None)[source]
Wrap an iterable in an ASCII progress bar on stderr.
Yields the items unchanged; the bar completes when iteration ends.
Notes
Uses a pure-text progress display (no Unicode block-bar column): rich’s default
BarColumnrenders with Unicode block characters that are not cp1252-encodable, which the console-encoding contract forbids.
- pytcl.diagnostics.log_filter_health(track_id, nis_value, nis_window, cov_condition)[source]
Log a per-track filter-health snapshot (NIS + covariance condition).
Guarded internally by
diagnostics_enabled()– callers on a hot path may call this bare without checking first, since a disabled namespace makes the call a single boolean-check no-op. Plain floats/sequences only; this module takes no dependency onpytcl’s tracker types.- Parameters:
track_id (Any) – Identifier of the track this health snapshot belongs to.
nis_value (float) – Normalized innovation squared for the current update.
nis_window (sequence of float) – Recent NIS history used as the local baseline for outlier detection. Includes the current sample, per call-site convention.
cov_condition (float) – Condition number of the track’s state covariance.
Notes
Symptomatic (logged at WARNING instead of DEBUG) when either:
nis_valueexceedsNIS_OUTLIER_FACTORtimes the mean ofnis_windowAND that mean is positive – with an empty or all-zero window the NIS branch cannot fire regardless ofnis_value, since any threshold scaled from a zero mean would flag everything – orcov_conditionexceedsCONDITION_WARN(covariance going numerically singular).
The caller owns
nis_window’s lifecycle; this function only reads it. Callers that keep a rolling window across an enable/disable toggle (asMultiTargetTrackerdoes) will blend pre-disable history into the first post-re-enable call – that’s a call-site persistence choice, not something this function corrects.
Rendering
Rich-based track tables and progress bars, ASCII-safe for redirected stdout on Windows.
Rich-based rendering: track tables and progress bars, ASCII-safe.
- pytcl.diagnostics.render.track_table(tracks, console=None)[source]
Render a summary table of tracks to the console.
- Parameters:
tracks (sequence) – Track objects with
id,status,state(and optionallycovariance) attributes, e.g. fromMultiTargetTracker.process.console (rich.console.Console, optional) – Target console; defaults to stderr. Output is ASCII-only (
box.ASCII) to satisfy the console-encoding contract.
- pytcl.diagnostics.render.progress_bar(iterable, description='working', total=None)[source]
Wrap an iterable in an ASCII progress bar on stderr.
Yields the items unchanged; the bar completes when iteration ends.
Notes
Uses a pure-text progress display (no Unicode block-bar column): rich’s default
BarColumnrenders with Unicode block characters that are not cp1252-encodable, which the console-encoding contract forbids.