Metadata-Version: 2.4
Name: viblearn
Version: 0.1.1
Summary: Scikit-learn style Python library for vibration signal analysis
Author: Viblearn Contributors
License-Expression: MIT
Keywords: vibration,signal-processing,condition-monitoring,fault-diagnosis,scikit-learn
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: Intended Audience :: Education
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.24
Requires-Dist: scipy>=1.10
Requires-Dist: scikit-learn>=1.3
Requires-Dist: matplotlib>=3.7
Requires-Dist: requests>=2.28
Requires-Dist: torch>=2.0
Requires-Dist: torchvision>=0.15
Requires-Dist: opencv-python-headless>=4.8
Requires-Dist: onnx>=1.15
Requires-Dist: onnxruntime>=1.17
Provides-Extra: dev
Requires-Dist: pytest>=7.4; extra == "dev"
Requires-Dist: pytest-cov>=4.1; extra == "dev"
Requires-Dist: ruff>=0.4; extra == "dev"
Dynamic: license-file

# Viblearn

**Scikit-learn compatible Python library for vibration signal analysis and bearing/gear fault diagnostics.**

Viblearn helps engineers and data scientists turn raw vibration signals into interpretable features, spectra, fault-frequency markers, and health indicators — with a familiar, composable API and no dependency on proprietary software.

---

## Features at a glance

| Module | What it provides |
|---|---|
| `viblearn.features` | `TimeDomainAnalyzer` (11 features), `FFTAnalyzer`, `PSDAnalyzer` (Welch), `FrequencyAnalyzer` (6 scalar), `EnvelopeAnalyzer` (HFRT), `CepstrumAnalyzer` |
| `viblearn.faults` | `FaultFrequencyCalculator` (BPFO/BPFI/BSF/FTF), `GearFrequencyCalculator` (GMF + sidebands), `FaultMarker` dataclass |
| `viblearn.synthetic` | 8 signal generators: sine, multi-sine, impulse train, bearing fault (ring-down), AM, gear mesh, beat, noisy |
| `viblearn.standards` | `iso_10816_3_severity()` (zones A–D), `api_670_limit()` (shaft displacement) |
| `viblearn.datasets` | `load_cwru()` — CWRU Bearing Dataset loader with local disk cache |
| `viblearn.plotting` | `plot_waveform`, `plot_spectrum`, `plot_psd`, `plot_envelope_spectrum`, `plot_fault_markers` |

All feature analyzers follow the scikit-learn `fit` / `transform` / `get_feature_names_out` API and are compatible with `sklearn.pipeline.Pipeline`.

---

## Installation

```bash
# Core (NumPy, SciPy, scikit-learn)
pip install viblearn

# With plotting support
pip install "viblearn[plot]"

# With CWRU dataset download support
pip install "viblearn[datasets]"

# Full development install
pip install -e ".[dev]"
```

Using [uv](https://github.com/astral-sh/uv) (recommended for Python 3.12+):

```bash
uv pip install "viblearn[plot,datasets]"
```

---

## Quickstart

### Synthetic signal generation

```python
import numpy as np
from viblearn.synthetic.signals import sine_signal, bearing_fault_signal, noisy_signal

# Pure sine
t, x = sine_signal(freq_hz=100.0, duration_s=1.0, fs=12000.0)

# Bearing fault (outer-race ring-down model)
t, x = bearing_fault_signal(
    fault_freq_hz=107.4,
    resonance_hz=3000.0,
    duration_s=1.0,
    fs=12000.0,
    snr_db=20.0,
)

# Add noise to an existing signal (returns array, not tuple)
x_noisy = noisy_signal(x, snr_db=15.0)
```

### Time-domain feature extraction

```python
from viblearn.features import TimeDomainAnalyzer

ta = TimeDomainAnalyzer()
features = ta.fit_transform(x.reshape(1, -1))   # shape (1, 11)
print(dict(zip(ta.get_feature_names_out(), features[0])))
# {'rms': ..., 'kurtosis': ..., 'crest_factor': ..., ...}
```

### FFT spectrum

```python
from viblearn.features import FFTAnalyzer

fa = FFTAnalyzer(fs=12000.0, nfft=8192, window="hann")
mag = fa.fit_transform(x.reshape(1, -1))[0]  # shape (4097,)
freqs = fa.frequencies()
```

### Envelope analysis (HFRT)

```python
from viblearn.features import EnvelopeAnalyzer

ea = EnvelopeAnalyzer(fs=12000.0, lowcut=1000.0, highcut=5000.0)
t, env = ea.fit_transform_signal(x)           # single-signal API
env_freq, env_mag = ea.envelope_spectrum(env)
```

### Bearing fault frequencies

```python
from viblearn.faults.bearing import BearingGeometry, FaultFrequencyCalculator

bg = BearingGeometry(
    rolling_elements=9,
    ball_diameter=0.20338,
    pitch_diameter=1.0,
    contact_angle=0.0,
)
calc = FaultFrequencyCalculator(bg, shaft_speed_hz=29.95)  # 1797 RPM
print(calc.all_fault_frequencies())
# {'BPFO': 107.36, 'BPFI': 162.19, 'BSF': 70.59, 'FTF': 11.93, '1x': 29.95, '2x': 59.90}
markers = calc.all_markers(n_harmonics=3)   # list[FaultMarker]
```

### Plotting with fault markers

```python
import matplotlib.pyplot as plt
from viblearn.plotting import plot_spectrum, plot_fault_markers

ax = plot_spectrum(freqs, mag, xlim=(0, 500))
plot_fault_markers(ax, markers, show_tolerance=True)
plt.savefig("spectrum.png")
```

### ISO 10816-3 severity and API 670 limit

```python
from viblearn.standards import iso_10816_3_severity, api_670_limit

result = iso_10816_3_severity(rms_velocity_mm_s=5.0, machine_class=2)
print(result)   # ISO 10816-3 Class 2 | 5.00 mm/s RMS → Zone B (Acceptable ...)

r = api_670_limit(speed_rpm=1797)
print(r)        # API 670 @ 1797 RPM | shaft limit = 283.08 mils pp ...
```

---

## scikit-learn Pipeline integration

```python
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestClassifier
from viblearn.features import TimeDomainAnalyzer

pipeline = Pipeline([
    ("features", TimeDomainAnalyzer()),
    ("scaler",   StandardScaler()),
    ("clf",      RandomForestClassifier()),
])
pipeline.fit(X_train, y_train)
```

---

## CWRU Bearing Dataset

```python
from viblearn.datasets import load_cwru

ds = load_cwru("OR", fault_diameter_in=0.007, load_hp=0)
print(ds)
# CWRUDataset(label='OR_0.007_0hp', n_samples=121265, fs=12000 Hz, duration=10.11s)
print(ds.shaft_speed_hz)   # 29.95 Hz (1797 RPM)
```

Files are cached at `~/.cache/viblearn/cwru/`. On first access they are downloaded from the CWRU server. If the server is unavailable, download the `.mat` files manually from the [CWRU bearing data center](https://engineering.case.edu/bearingdatacenter/data-files) and place them in the cache directory.

---

## Standards reference

### ISO 10816-3 — vibration severity zones (RMS velocity, mm/s)

| Class | A/B | B/C | C/D | Machinery |
|---|---|---|---|---|
| 1 | 2.3 | 4.5 | 7.1 | Large (>15 kW), rigid foundation |
| 2 | 3.5 | 7.1 | 11.0 | Medium (15–300 kW) |
| 3 | 3.5 | 7.1 | 11.0 | Pumps, multi-vane impellers |
| 4 | 7.1 | 11.0 | 18.0 | Large (>300 kW), flexible foundation |

### API 670 — shaft displacement limit (mils peak-to-peak)

```
limit = 12 000 / sqrt(N_rpm)
```

---

## Examples

```bash
python examples/quickstart.py              # full pipeline (features + plotting)
python examples/synthetic_bearing_demo.py  # envelope analysis with BPFO markers
```

---

## Development

```bash
git clone https://github.com/Liang-Guo-SD/viblearn
cd viblearn
uv venv .venv --python 3.12
uv pip install -e ".[dev]"
.venv/bin/pytest           # 105 tests
.venv/bin/ruff check src/  # linting
```

---

## Scope

**In scope:** signal features, spectral analysis, envelope (HFRT), cepstrum, fault frequencies, synthetic signals, CWRU dataset loader, plotting helpers, ISO 10816-3 / API 670 helpers.

**Out of scope (MVP):** digital twin simulation, full diagnosis expert systems, predictive maintenance decision engines, PLC/SCADA/OPC-UA, rotor dynamics simulation, FEM solvers.

---

## Reference

Randall, R.B., *Vibration-Based Condition Monitoring*, 2nd ed. (Wiley, 2021).

---

## License

MIT
