Skip to main content

telemetry-anomdet

Documentation Test PyPI PyPI Testing License

telemetry-anomdet is an open-source anomaly detection toolkit for spacecraft telemetry. It runs classical and graph-based deep detectors behind one interface, selects alarm thresholds without labels, and distills a trained detector down to Power of Ten conformant C that runs on flight hardware. Per-channel SHAP attribution and LLM-generated diagnostic reports are on the roadmap.

Benchmarked on SMAP (NASA). MSL (NASA) and ESA-ADB (ESA) results land in v0.3.0.


Getting Started
Installation and setup
API Reference
BaseDetector, models, ensemble
Tutorial
End-to-end detection example
Pipeline Overview
Ingest, detect, explain
Discussions
Questions and feedback

Quick Install

# recommended
uv add telemetry-anomdet

# or with pip
pip install telemetry-anomdet

The base install is torch-free. The deep detectors (GDN, KANGDN) need the deep extra:

uv add "telemetry-anomdet[deep]"

Example Usage

Fit the Ensemble on Nominal Telemetry

All detectors are trained on nominal data only, no anomaly labels used during training. Labels are used exclusively for evaluation.

import numpy as np
from telemetry_anomdet.models.unsupervised.pca import PCAAnomaly
from telemetry_anomdet.models.unsupervised.kmeans import KMeansAnomaly
from telemetry_anomdet.models.ensemble import AnomalyEnsemble

# X_train: (n_windows, window_size, n_features), produced by windowify()
X_train = ...

ensemble = AnomalyEnsemble(
    models = {
        "pca":    PCAAnomaly(n_components = 10),
        "kmeans": KMeansAnomaly(n_clusters = 5, scale = True),
    },
    combine = "mean",
    normalize = "robust",
    percentile = 95.0,
)

ensemble.fit(X_train)

Inference and Anomaly Flags

scores = ensemble.decision_function(X_test)   # higher = more anomalous
flags  = ensemble.is_anomaly(X_test)          # boolean mask at training threshold

# Runtime sensitivity override, no retraining needed
flags_strict = ensemble.is_anomaly(X_test, percentile = 98.0)
flags_custom  = ensemble.is_anomaly(X_test, threshold = 0.75)

Per-Model Score Decomposition

score_components() returns raw per-model scores before normalization or combination. This is the SHAP hook: perturb input channels, measure how each sensor drives each model's score independently.

components = ensemble.score_components(X_test)
# {"pca": array(100,), "kmeans": array(100,)}

Getting the SMAP dataset

The benchmarks and examples need a local copy of the NASA SMAP/MSL data, which is not redistributed with the toolkit. From the root of the repo:

pip install kaggle

# Requires a Kaggle API key in ~/.kaggle/kaggle.json
kaggle datasets download -d patrickfleith/nasa-anomaly-detection-dataset-smap-msl \
  && mv nasa-anomaly-detection-dataset-smap-msl.zip data.zip \
  && unzip -o data.zip \
  && rm data.zip \
  && mv data/data tmp && rm -r data && mv tmp data

That leaves data/train/, data/test/ and labeled_anomalies.csv. Point the examples at it:

export TAD_SMAP_DIR=data          # Windows: $env:TAD_SMAP_DIR = "data"
python examples/smap_demo.py
python examples/smap_benchmark.py

Datasets are never committed; data/ is gitignored.

Coming in Phase 3+

# Per-channel SHAP attribution (Phase 3)
# shap_values = explainer.explain(ensemble, X_anomalous)
# {"sensor_01": 0.42, "sensor_02": 0.18, ...}

# LLM diagnostic report (Phase 4)
# report = llm_engine.explain(shap_values, context, channel_names)
# DiagnosticReport(
#     anomaly_type = "power subsystem fault",
#     severity = "high",
#     primary_channels = ["sensor_01", "sensor_07"],
#     explanation = "...",
#     recommended_action = "...",
#     confidence = 0.87,
# )

Features

Available now

  • One interface for every detector. Classical and deep detectors share the same fit / decision_function / predict / is_anomaly API, so stacking or swapping models needs no per-model glue.
  • Graph deviation detectors. GDN and KANGDN forecast each channel from its learned top-k neighbours and score the deviation, catching readings that are individually plausible but wrong in relation to each other.
  • Alarms without labels. threshold_for_budget and dynamic_threshold pick an operating point from the score distribution alone. Operations can state an alarm rate; they cannot state a recall they have no way to observe.
  • Honest evaluation. Event-level scoring alongside the conventional point-adjusted F1, plus a random baseline row in the benchmark, because point-adjusted F1 rates uniform random noise above every trained configuration on SMAP.
  • Runs on flight hardware. A fitted KANGDN distills to a torch-free NumPy evaluator, then to Power of Ten conformant C with golden vectors. Host and ESP32-S3 targets are in targets/.
  • Stacking ensemble with robust (median + IQR) score normalization, built for anomaly scores that are extreme by definition.
  • Per-model score decomposition via score_components(), the hook that enables per-channel attribution without retraining.
  • Spacecraft-native ingestion. SMAP and CSV load straight into a long-form TelemetryDataset, no schema wrangling.
  • Runtime sensitivity control. is_anomaly() accepts a percentile or threshold override, so operators re-tune without retraining.

On the roadmap

  • TranAD: transformer-based sequence reconstruction
  • SHAPExplainer: per-channel attribution over score_components() (Phase 3)
  • LLM diagnostic reports, SHAP chart supplied as an image (Phase 4)
  • Human-in-the-loop threshold feedback (Phase 5)
  • MSL results, using the existing SMAP loader (spacecraft = "MSL") (v0.3.0)
  • ESA-ADB evaluation: the multivariate benchmark that exercises the graph (v0.3.0)

AI Transparency

AI assistants are used while writing and maintaining this project's documentation: drafting API reference pages, tightening prose, and catching claims that go stale.

What that does not change:

  • Numbers come from runs. Benchmark figures are produced by examples/smap_benchmark.py, and the hardware results in the deployment docs are measured on an ESP32-S3 by the conformance harness in targets/. Nothing quoted in these docs is estimated or inferred.
  • Behavior claims are backed by tests. The suite gates CI, and the documented API is covered by it.

Everything published here is reviewed before it lands.

Getting Help

Discussions

To suggest improvements, or ask for help, please see GitHub Discussions

Bug reports

To submit a report on any bugs or issues, open an issue here

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

telemetry_anomdet-0.2.0.tar.gz (96.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

telemetry_anomdet-0.2.0-py3-none-any.whl (77.1 kB view details)

Uploaded Python 3

File details

Details for the file telemetry_anomdet-0.2.0.tar.gz.

File metadata

  • Download URL: telemetry_anomdet-0.2.0.tar.gz
  • Upload date:
  • Size: 96.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for telemetry_anomdet-0.2.0.tar.gz
Algorithm Hash digest
SHA256 7e0a3b11a849979a9a2eeb98ef7d6de435c20e7f3a24fb278b6463451a788462
MD5 a00ac890b11c8c6d8342ad456bae2690
BLAKE2b-256 99dc4122f9eb9007a5d9a00108209ebe3e9e0bfa765584d42a481d1cfdeb5b91

See more details on using hashes here.

Provenance

The following attestation bundles were made for telemetry_anomdet-0.2.0.tar.gz:

Publisher: publish.yml on JulioAnzaldo/telemetry-anomdet

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file telemetry_anomdet-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for telemetry_anomdet-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1e3e2fd2a6abbf106731f5981eaa9c0dab1e64d7c0048774039cc9fd7b6cd55e
MD5 9d72f877324dd6a4dc07307457073d4c
BLAKE2b-256 03bdbbab76d992e3111baffd95bfa36bf7c61e85e9f05e98ab7eda92b4d074ab

See more details on using hashes here.

Provenance

The following attestation bundles were made for telemetry_anomdet-0.2.0-py3-none-any.whl:

Publisher: publish.yml on JulioAnzaldo/telemetry-anomdet

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page