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

Metadata

Release files for telemetry-anomdet 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for telemetry-anomdet 0.2.0
File Size Uploaded Provenance
telemetry_anomdet-0.2.0.tar.gz 96.3 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for telemetry-anomdet 0.2.0
File Interpreter ABI Platform
telemetry_anomdet-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 173.4 kB

Release files / telemetry_anomdet-0.2.0.tar.gz

Download URL telemetry_anomdet-0.2.0.tar.gz
Size 96.3 kB
Tags Source
SHA-256 checksum
How to use checksums
7e0a3b11a849979a9a2eeb98ef7d6de435c20e7f3a24fb278b6463451a788462
BLAKE2b-256 checksum
How to use checksums
99dc4122f9eb9007a5d9a00108209ebe3e9e0bfa765584d42a481d1cfdeb5b91
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 14, 2026.

Transparency log

Release files / telemetry_anomdet-0.2.0-py3-none-any.whl

Download URL telemetry_anomdet-0.2.0-py3-none-any.whl
Size 77.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
1e3e2fd2a6abbf106731f5981eaa9c0dab1e64d7c0048774039cc9fd7b6cd55e
BLAKE2b-256 checksum
How to use checksums
03bdbbab76d992e3111baffd95bfa36bf7c61e85e9f05e98ab7eda92b4d074ab
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 14, 2026.

Transparency log

Security for telemetry-anomdet 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for telemetry_anomdet-0.2.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 14, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files Full provenance

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