pyOutRun 0.1.0
Functions for analyzing runout and form deviations of rotating shafts
Requires Python: >=3.9

<!--
SPDX-FileCopyrightText: Copyright © 2024-2026 Damian Anders <damian.anders@tu-dresden.de>

SPDX-License-Identifier: AGPL-3.0-or-later
-->

pyOutRun
--------

![License](https://img.shields.io/badge/license-AGPL--3.0-blue)
![Python](https://img.shields.io/badge/python-3.9%2B-blue)

**pyOutRun** is a Python library for the analysis of **shaft runout, eccentricity, and form deviations**. It provides a suite of tools for signal processing, spectral analysis, and geometric fitting, specifically tailored for precision metrology and experimental mechanics of rotating machinery.

The authors would like to thank VolkswagenStiftung for funding the project “Open Science Hardware Instrumente für wissenschaftliche Experimente” as part of the program “Pioniervorhaben - Impulse für das Wissenschaftssystem”.

# Disclaimer
The software provided here is provided without any warranty of any kind. The use of this project is expressly at the user's own risk. The author(s) and contributors assume no liability for damages, losses or legal claims that may arise from the use, copying, modification or distribution of the project, unless these are based on intent or gross negligence.

Any changes or adaptations to this project are made at the user's own risk. The author(s) and contributors assume no responsibility for unforeseeable risks arising from such modifications.
The author(s) and contributors do not guarantee the suitability, reliability, availability, accuracy or completeness of the project and its documentation. No warranty is given that the project is error-free, nor that any errors will be corrected.
Always verify results independently and validate against your own reference data and domain knowledge before relying on them in engineering decisions.


# Features

*   **Rotational Speed Estimation**: Detect rotational frequency directly from displacement spectra (`rotation_spectrum`) or angular position signals (`rotation_angle`).
*   **Runout Analysis**:
    *   **`runout_fit`**: Fits physical eccentricity models to multi-sensor data using differential evolution.
    *   **`runout_jansen`**: Implements the Jansen method to separate eccentricity (orbit) from form deviation (roundness) using multi-probe setups.
*   **Signal Simulation**: Generate synthetic sensor signals for eccentric shafts with defined roundness errors and noise (`eccentricity_geometry`, `simulate_roundness_error`).
*   **Signal Conditioning**: Specialized tools for harmonic suppression, corrected real-FFT (with Tukey windows), and SNR adjustment.

# Installation

This package requires **Python 3.9+**.

```bash
pip install pyOutRun
```
# Quick Start
## 1. Estimate Rotation Frequency from Vibration Data
```python
import numpy as np
import pyOutRun as por
```

Generate dummy signal: 100 Hz sampling, 12.5 Hz rotation
```python
fs = 100.0
t = np.arange(0, 10, 1/fs)
signal = 0.5 * np.sin(2 * np.pi * 12.5 * t) + 0.1 * np.random.randn(len(t))
```

Calculate Spectrum
```python
spec, freq = por.rfft_tukey_corrected(signal, fs)
```
Detect Rotation Speed
```python
f_rot, _, used_harmonics = por.rotation_spectrum(freq, spec, verbose=True)
print(f"Detected Rotation: {f_rot:.2f} Hz")
```

## 2. Fit an Eccentricity Model
```python
# Assuming 'time_data' and 'sensor_matrix' (N samples x K sensors) exist
result = por.runout_fit(
    x_vector=time_data,
    y_array=sensor_matrix,
    radius=10.0,
    fitfunc='exc'  # 'exc' = full eccentric model, 'cos' = cosine approximation
)

print(f"Optimized Rotation Freq: {result.x[0]:.4f} Hz")
print(f"Eccentricity Magnitude: {result.x:.4f} mm")
```

# Documentation
## Core Modules
### `runout_fit`
Fits a geometric model to sensor data.
*   **`runout_fit(x_vector, y_array, radius, fitfunc='exc', ...)`**
    *   `x_vector`: Time stamps.
    *   `y_array`: Sensor data columns.
    *   `fitfunc`: `'exc'` for exact geometry, `'cos'` for simple cosine approximation.
    *   Returns: `scipy.optimize.OptimizeResult`. Parameters `x` contain `[f_rot, eccentricity, angle_s1, offset_s1, ...]`.

### `runout_jansen`
Separates shaft movement from surface profile (Multi-probe error separation).
*   **`runout_jansen(sensor_signals, sensor_pos, samples_per_rev, orientation='co', ...)`**
    *   `sensor_signals`: Matrix of sensor readings.
    *   `sensor_pos`: Angular positions of sensors (in radians).
    *   `orientation`: Coordinate system orientation (`'co'`-rotating or `'counter'`-rotating).
    *   Returns: `(eccentricity_xy, radius_deviation)`.

### `rotation_spectrum`
Analyzes frequency spectrum to find the fundamental rotation speed.
*   **`rotation_spectrum(frequency_lines, spectrum, ...)`**
    *   Uses harmonic prominence to identify the base frequency even in noisy data.
    *   Can estimate relative sensor angles if multi-channel spectra are provided.

## Utility Modules

*   **`rfft_tukey_corrected`**: FFT implementation that correctly scales amplitudes for real-world signals (doubles non-DC components) and applies Tukey windowing to reduce leakage.
*   **`harmonic_suppression`**: Tools to filter out specific harmonic orders from a signal.
*   **`eccentricity_geometry`**: Forward simulation of sensor values given geometric parameters (useful for generating test data).

# License

This project is licensed under the **AGPL-3.0-or-later**. See the `LICENSES/` directory for details.