Skip to main content

Functions for analysing runout and shape deviations in rotating shafts

Project description

pyOutRun

License Python

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pyoutrun-1.0.1.tar.gz (48.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pyoutrun-1.0.1-py3-none-any.whl (47.4 kB view details)

Uploaded Python 3

File details

Details for the file pyoutrun-1.0.1.tar.gz.

File metadata

  • Download URL: pyoutrun-1.0.1.tar.gz
  • Upload date:
  • Size: 48.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for pyoutrun-1.0.1.tar.gz
Algorithm Hash digest
SHA256 582ff40eb89b51e9fa42fa98a6e0807aee5f0ffa88f66fd8e9435a6b020adbaa
MD5 9b13b73e058f6d71e6413a83d2f39eef
BLAKE2b-256 321b8d9e9c1cd52f2481f7d98878be6a3e253eb14e6fbcb3058b17554efe5654

See more details on using hashes here.

File details

Details for the file pyoutrun-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: pyoutrun-1.0.1-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.4

File hashes

Hashes for pyoutrun-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 c7f8cc69e442578d09a4661675426fb77e25c78b30ecf5363779c5ca1ba15f96
MD5 331412c9f39d0e601579a1a4f05ac478
BLAKE2b-256 38bee2c4b35f4a8a704e92d6ba61d29d48a6ddab73473def8310f01c86beb279

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page