Signal fingerprinting for unknown physical signals — physics atlas + spectral matching
Project description
spectroprint
Signal fingerprinting for unknown physical signals.
Given a measured 1D signal, spectroprint compares its spectral-entropic fingerprint against an atlas of known physical functions and element emission spectra, and returns a ranked similarity landscape — not a single answer, but the full distribution of compatible hypotheses.
from spectroprint import PhysicsAtlas
atlas = PhysicsAtlas(instrument="uv_vis")
report = atlas.match(my_signal)
print(report)
spectroprint — similarity landscape
instrument : uv_vis | signal length : 512
──────────────────────────────────────────────────────────────
┌ Cluster 1 (97.4% – 100.0%)
│ 1. Chirp 100.0%
│ 2. Discrete curvature 97.4%
└
┌ Cluster 2 (77.8% – 89.3%)
│ 3. Airy function 89.3%
│ 4. Damped sine 88.8%
│ 5. Fano resonance 84.2%
└
──────────────────────────────────────────────────────────
39 entries compared against atlas.
The idea
Most signal analysis tools ask "what is this signal?" and return a single answer.
spectroprint asks a different question: what is this signal compatible with?
The library does not decide. It presents the full similarity landscape so the physicist can interpret it. Close matches are flagged as ambiguous. A large gap between clusters signals a confident separation.
How it works
Every signal has a shape fingerprint — a fixed-length vector of spectral and statistical features that is completely invariant to amplitude:
| Feature | What it captures |
|---|---|
| Spectral centroid | Where the energy is concentrated |
| Spectral bandwidth | How spread out the spectrum is |
| Spectral flatness | Tonal vs noise-like character |
| Shannon entropy | Complexity / disorder |
| Kurtosis | Tail weight / impulsivity |
| Skewness | Asymmetry |
| Zero-crossing rate | Oscillation density |
| Spectral rolloff | Where 85% of energy falls |
| Hurst exponent | Long-range memory / persistence |
This fingerprint is compared against every entry in the physics atlas — 44 mathematical families and 21 element emission spectra — using cosine similarity on z-scored features. The result is a full ranked distribution, grouped into clusters by proximity.
Installation
pip install spectroprint
Requirements: Python >= 3.10, NumPy, SciPy.
Quick start
import numpy as np
from spectroprint import PhysicsAtlas
atlas = PhysicsAtlas(instrument="uv_vis")
t = np.linspace(-6, 6, 512)
signal = np.exp(-0.3 * np.abs(t)) * np.sin(3 * np.pi * t / 4)
report = atlas.match(signal)
print(report)
# Top match
print(report.top.label) # "Damped sine"
print(report.top.similarity) # 91.3
print(report.top.interpretation) # "Damped oscillator..."
# Iterate clusters
for cluster in report.clusters:
print(cluster)
# Raw fingerprint
fp = atlas.fingerprint(signal)
# {'spectral_centroid': 0.12, 'shannon_entropy': 4.8, ...}
Instrument presets
atlas = PhysicsAtlas(instrument="uv_vis") # 200-780 nm (default)
atlas = PhysicsAtlas(instrument="visible") # 380-780 nm
atlas = PhysicsAtlas(instrument="uv") # 200-400 nm
atlas = PhysicsAtlas(instrument="nir") # 780-2500 nm
atlas = PhysicsAtlas(instrument="vis_nir") # 380-1100 nm
atlas = PhysicsAtlas(instrument="plasma_vis") # 380-780 nm (ICP-OES, arc/spark)
atlas = PhysicsAtlas(instrument="solar") # 300-1000 nm (Fraunhofer lines)
atlas = PhysicsAtlas(instrument="full") # 200-2500 nm (simulation)
# Custom range (advanced)
atlas = PhysicsAtlas.custom(wl_min=450, wl_max=700)
The atlas — 65 entries
Mathematical families (44)
| Category | Entries |
|---|---|
| Resonance | Gaussian, Lorentzian, Voigt, Double Gaussian, Double Lorentzian, Fano resonance, Damped sine, Sech2 soliton, Gaussian derivative, Gaussian x sine |
| Phase transitions | Sigmoid, Tanh critical, Landau order parameter, Cusp catastrophe, Critical power law, Finite-size scaling |
| Complex systems | Stretched exponential, Power law with cutoff, SOC proxy (1/f^1.5), Percolation threshold, Scale-free power law |
| Information | KL divergence proxy, Mutual information decay, Markov autocorrelation |
| Dynamics | AR(1) process, Response function, Memory kernel, Hysteresis proxy, Exponential decay, Chirp |
| Geometry | Discrete curvature, Geodesic proxy, Distance to manifold, Airy function |
| Signals | Sine, Cosine, Sinc, Step, Square, Sawtooth, Triangle |
| Noise | White noise, Pink noise (1/f), Brown noise (1/f2) |
Element emission spectra (21)
H, He, Li, Na, K, Ca, Mg, Fe, Cu, Zn, Hg, Ne, Ar, Sr, Ba, Cr, Mn, Ni, Pb, Cd, plus Hg calibration lamp.
Lines from the NIST Atomic Spectra Database, modeled as Lorentzian profiles. Each match preserves both layers of information:
Lorentzian | Sodium (Na)
[element] Sodium D doublet. Flame tests (yellow), street lamps, solar Fraunhofer lines.
Reading the output
Clusters
Matches are grouped by proximity. A tight cluster means those hypotheses are indistinguishable by fingerprint alone — additional physical reasoning is needed to separate them.
Ambiguity flag
When the gap between the top two matches is below the threshold (default 5%), the report is flagged:
Ambiguous top cluster (gap < 5%). Multiple hypotheses are equally compatible.
This is intentional. The library does not force a single answer when the evidence is insufficient.
Amplitude invariance
The fingerprint is amplitude-normalized. A Gaussian at 1 mW and at 1 kW produce identical fingerprints. What matters is the shape, not the intensity.
Atlas validation
report = atlas.validate(separation_threshold=5.0)
print(report)
# Shows all atlas pairs that are too close to distinguish reliably
Design philosophy
- Hypotheses, not conclusions. The output is a ranked similarity distribution, not a classification.
- Shape over intensity. Amplitude is never part of the fingerprint.
- Ambiguity is shown, not hidden. When evidence is insufficient, the report says so.
- Two layers of meaning. Every match carries the mathematical form and the physical interpretation.
- Instrument-aware. Elements with no lines in your measurement range are excluded automatically.
Roadmap
- v0.2 — Composition grammar:
Gaussian * Lorentzian,Exponential + Sine, physically motivated combinations as new atlas entries - v0.3 — Larger atlas (200+ entries), user-extensible families
- v0.4 — Visualization: similarity heatmap, fingerprint radar chart
- v0.5 — Optional ML-based embedding for higher-dimensional feature discrimination
Author
Franco Fitte
License
MIT
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 spectroprint-0.1.0.tar.gz.
File metadata
- Download URL: spectroprint-0.1.0.tar.gz
- Upload date:
- Size: 15.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
588d53cbc3f08cdf6c98ffddfd1b905f48883db993378f012affc53e2c608a96
|
|
| MD5 |
d9249d621fb92f6f379a4cad7a0adb80
|
|
| BLAKE2b-256 |
5078594f0f52d6e9416763045b6cef4b8841b25d0cbd473b307398c1849547dd
|
File details
Details for the file spectroprint-0.1.0-py3-none-any.whl.
File metadata
- Download URL: spectroprint-0.1.0-py3-none-any.whl
- Upload date:
- Size: 4.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
785a4fd988086618ddca6c44614f169c3fc8202e13d3b96e87a8738f4d60d8db
|
|
| MD5 |
52c928e01616f9b6757076b6b99aeca9
|
|
| BLAKE2b-256 |
498c2864c41e9c2636edb77f4e5dff8dcf38b785be5b1a594e55a422fc5292f3
|