Functions for analysing runout and shape deviations in rotating shafts
Project description
pyOutRun
pyOutRun is a Python package for performing runout analyses on rotating shafts and workpieces. It provides tools for fitting eccentric motion models, separating spindle eccentricity from true surface geometry using multi-probe methods, and simulating synthetic test signals for validation purposes.
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”.
Overview
Disclaimer
THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT.
pyOutRun is a research and engineering tool developed at TU Dresden. It is NOT certified for use in safety-critical applications. The authors and contributors accept NO LIABILITY for any damages, losses, or injuries arising from the use or misuse of this software. Results produced by this package must be independently verified by qualified personnel before being used in any decision-making process, manufacturing workflow, or quality assurance procedure.
Users are responsible for validating that the algorithms, models, and outputs are appropriate for their specific application. The cosine approximation model ('cos') and the exact eccentric model ('exc') each carry inherent assumptions and limitations — using them outside their valid operating range may produce incorrect or misleading results without warning.
This software is licensed under the GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later). By using this software, you agree to comply with all terms of this license, including the requirement to make source code available when providing network access to the software.
Table of Contents
Features
- Eccentricity fitting via differential evolution with both exact geometric and cosine approximation models
- Multi-probe runout separation (Jansen method) to isolate spindle error motion from workpiece form deviations
- Synthetic signal generation for eccentrically rotating circles and random surface profiles
- Rotation angle analysis to identify regions of constant rotational speed from encoder signals
- Reference angle detection from signal flanks/impulses with automatic threshold optimization
- Corrected FFT utilities with proper normalization for real-valued signals and Tukey windowing
- Harmonic suppression analysis via condition number evaluation of sensor position matrices
- Signal resampling to align harmonics of a base frequency with FFT frequency bins
- Noisy fit evaluation tools for robustness and sensitivity analysis at controlled SNR levels
- Numba-accelerated fitness functions and linear algebra kernels for high performance
Installation
pip install pyOutRun
Quick Start
An Examples Jupyter Notebook (Examples.ipynb) is included in the repository for an interactive quick start. It walks through the complete workflow — from generating synthetic data with eccentricity, form deviations, and noise, to fitting parameters and separating runout components.
Below is a minimal example:
import numpy as np
import pyOutRun as por
# Setup
fSampling = 10_000.0 # Hz
fRot = 5 # Hz
tMax = 10 # s
radius = 1.0
runout = 0.01
t = np.linspace(0, tMax, num=int(fSampling * tMax), endpoint=False)
phi = 2 * np.pi * fRot * t
posSensors = [0.0, 1.0, np.pi, 3.8]
# Generate synthetic eccentric signals
signals, *_ = por.eccentric_signals(phi, radius, [runout, 0.0], posSensors)
# Fit eccentricity model
res = por.fit_eccentricity(t, signals, fit_function='cos')
print(f"Fitted rotation frequency: {res.x[0]:.3f} Hz")
# Separate eccentricity from form deviation
eccentricity, radius_phi, phi_out = por.runout_multiprobe(
signals, np.asarray(posSensors), fSampling, fRot
)
For the full walkthrough including visualization, see the Examples notebook.
Module Overview
fit_eccentricity
Core module for fitting geometric models to shaft runout and eccentricity data using differential evolution optimization. Supports exact eccentric geometry ('exc') and simplified cosine ('cos') models, with automatic boundary estimation from spectral analysis.
runout_multiprobe
Implements the multi-probe separation method to decompose measured sensor signals into spindle eccentricity (radial error motion) and true workpiece radius variations (form deviations) in the frequency domain.
generate_geometry
Provides simulation tools for generating synthetic position sensor signals from an eccentrically rotating circle, as well as random surface profiles with controlled spectral content.
rotation_angle
Utilities for identifying regions of constant rotational speed from angle encoder signals and extracting the corresponding frequency via linear fitting.
reference_angle
Functions for detecting reference impulses (flanks) in periodic signals and computing their angular positions, with automatic threshold optimization and optional lowpass filtering.
rfft_corrected
FFT utilities that apply Tukey windowing and correct normalization for real-valued input signals, along with the corresponding inverse transform.
harmonic_suppression
Evaluates the condition numbers of the frequency-dependent sensor position matrix, which characterizes how well harmonics can be separated for a given sensor arrangement.
resample
Resamples time-domain signals so that harmonics of a specified base frequency align exactly with FFT frequency bins, using cubic spline interpolation and zero-padding.
evaluate_noisy_fit
Testing and validation utilities that apply controlled noise at a target SNR to clean signals and evaluate fitting performance, useful for sensitivity and robustness analysis.
API Reference
pyOutRun.fit_eccentricity
fit_eccentricity(time_values, signal, radius=1.0, fit_function='exc', bounds=None, angle_tol=5, position_zero=True, tukey_alpha=0.2, f_lowpass=None)
Fit a mathematical model to eccentric motion data using differential evolution. Estimates rotational frequency, eccentricity magnitude, and sensor-specific parameters (angular positions and offsets) by minimizing the squared error between measured signals and a geometric model. Supports both an exact eccentric geometry model and a simplified cosine approximation. If bounds is None, plausible boundaries are automatically estimated from the signal spectra. Returns a scipy.optimize.OptimizeResult whose x attribute contains [fRot, eccentricity, angle_s1, offset_s1, ..., angle_sN, offset_sN].
pyOutRun.runout_multiprobe
runout_multiprobe(sensor_sig, sensor_pos, f_sampling, f_rotation, n_min=2, n_max=100, tukey_alpha=0.02, coordinate_system='co')
Calculate eccentricity, radius variations, and the angle vector from multiprobe sensor signals. Resamples time-domain signals into the angular domain, computes Fourier spectra, applies the multi-probe mathematical separation on a defined range of harmonic frequencies, and transforms the separated spectra back into the angular domain. Returns a tuple of (eccentricity, radius_phi, phi) where eccentricity contains x/y components of radial error motion, radius_phi contains true radius variations, and phi is the corresponding angle vector.
pyOutRun.generate_geometry
eccentric_signals(phi, radius, exzentrizitaet, posSensor, modus='xy')
Simulate position sensor signals for an eccentrically rotating circle. Computes the displacement signals that would be observed by sensors at specified angular positions around a shaft with a given eccentricity. The eccentricity can be specified in Cartesian ('xy') or polar ('ra') coordinates. Returns a tuple of (delta_s, gamma, l_1) — the simulated signals, the angles between the x-axis and the sensor-circle intersection, and the parallel component of the centre point shift. All angles are in radians.
surface_profile(phi, f_crit, seed=555, filter_order=10)
Generate a simulated surface profile with random form deviations. Creates a synthetic roundness error signal by applying a Butterworth low-pass filter to normally distributed random values. Ensures the generated profile is smooth and continuous at the 2π→0 transition. Returns a normalized (std=1) array of radial deviations. Raises an exception if no matching continuous segment is found within the search limit — in that case, change the seed parameter.
pyOutRun.rotation_angle
angle_values_to_rotation(time_values, angle_values, percentage=75)
Calculate the velocity (slope) and offset of an angle signal over time. Determines the rotational speed by computing the gradient of the angle sequence, selecting values above a specified percentile, and performing a linear least-squares fit. Returns a tuple (speed, offset). Raises ValueError if no valid angle gradients are found above the specified percentile.
find_constant_angle_slope(time_values, angle_values, fit_slope, fit_intercept, percentage=25)
Find the slice indices of the longest continuous segment matching a linear fit. Calculates the absolute deviation between a linear fit and measured values, determines a maximum deviation threshold using the specified percentile, and identifies the longest contiguous block of points below this threshold. Returns a 1D array [start, end] where end is incremented by 1 for direct use in array slicing. Raises ValueError if no constant gradient region is found.
pyOutRun.reference_angle
angle_position_flanks(phi, signal, threshold_percentile=None, lowpass_harmonics=500)
Calculate the angular positions of signal flanks (positive impulses) and the offset. Processes a 2D signal array and its corresponding angle array to find the centers of positive impulses. Optionally applies a Butterworth lowpass filter and can automatically determine an optimal threshold percentile for flank detection. Returns (phi_center, offset) where phi_center contains relative angular positions shifted so the first channel is at 0, and offset is the absolute angular position of the first channel's impulse. Raises ValueError for mismatched input dimensions or invalid percentile values.
pyOutRun.rfft_corrected
rfft_tukey_corrected(x, fs, axis=0, tukey=0.05)
Apply a Tukey window to the input signal, perform a normalized real-valued FFT (RFFT), and correct the spectrum for a real-valued input signal. Also computes the corresponding frequency values. Returns a tuple (spectrum, freq).
irfft_corrected(spektrum, axis=0)
Compute the inverse real-to-complex FFT after reversing the amplitude normalization applied by rfft_tukey_corrected. Returns the real-valued time-domain signal.
pyOutRun.harmonic_suppression
sensor_angle_condition_numbers(freq, positions)
Determine the condition numbers of the frequency-dependent sensor position matrix from the sensor angular positions and the frequency lines. This is useful for evaluating how well a given sensor arrangement can separate harmonics at each frequency. Returns an array of condition numbers corresponding to each frequency line. Accelerated with Numba.
pyOutRun.resample
resample_to_harmonics(x_vector, y_array, f_sampling, f_base, tukey_alpha)
Resample and zero-pad a signal so that harmonics of a base frequency align exactly with FFT frequency bins. Uses cubic spline interpolation for resampling and applies a Tukey window before padding. The sampling rate is only ever reduced, never increased. Returns (y_array_resampled, x_array_resampled, f_s_resampled, steps) where steps is the number of frequency bins between consecutive harmonics. Raises ValueError for invalid input dimensions, parameter ranges, or frequency constraints.
pyOutRun.evaluate_noisy_fit
evaluate_noisy_fit(time_values, signal, noise, SNR, radius, fit_function, bounds, f_lowpass)
Evaluate fitting performance by applying controlled noise to a clean signal. Scales a noise vector to reach a target Signal-to-Noise Ratio (SNR), adds it to the reference signal, and performs a runout fit. Used to assess how accurately parameters can be recovered from noisy measurements. Returns a scipy.optimize.OptimizeResult.
getNoiseScaling(signal, noise, SNR)
Determine the scaling factor by which a noise vector must be multiplied to achieve a desired SNR relative to a given signal. Returns 0 for infinite SNR (no noise).
pyOutRun._protocols
FitFunction (Protocol)
A typing protocol defining the interface for custom fitness functions that can be passed to fit_eccentricity. A conforming callable must accept (params, xVektor, yArray, *args) and return a np.float64 scalar representing the cost.
Dependencies
For running the Examples notebook:
License
This project is licensed under the GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later).
See the LICENSES folder for the full license texts.
Copyright
© 2024–2026 Damian Anders damian.anders@tu-dresden.de
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 pyoutrun-1.0.0.tar.gz.
File metadata
- Download URL: pyoutrun-1.0.0.tar.gz
- Upload date:
- Size: 48.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cdf0c1e4d47842de5cb8416751dc456188c1e281f8a78839a585f8a4d95a0d53
|
|
| MD5 |
57b1d724b8c2f666a9a9de30cd3779ab
|
|
| BLAKE2b-256 |
85bc5c5594d2dc31d43e8924b280b9e462a080b7a6b17bc1ea10b13addcd283a
|
File details
Details for the file pyoutrun-1.0.0-py3-none-any.whl.
File metadata
- Download URL: pyoutrun-1.0.0-py3-none-any.whl
- Upload date:
- Size: 47.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
97ac92a56c3acbaca0dd7e4f3d4f550fc1ff109148cd424dc88a614f2231580a
|
|
| MD5 |
7cdd3fda2ef9905f7cfb22f035da492e
|
|
| BLAKE2b-256 |
43e85c8c1f1e362d846a11dd0052406cbab2a117a642aaf943105136bf71a076
|