High-performance C extensions for image processing and curve fitting.
| Export | Description |
|---|---|
fmedian |
Local median filter (2D/3D auto-dispatch) |
fmedian2d, fmedian3d |
Direct 2D/3D median |
fsigma |
Local ? filter (2D/3D auto-dispatch) |
fsigma2d, fsigma3d |
Direct 2D/3D sigma |
fgaussian_f32, fgaussian_f64 |
Gaussian profile (Accelerate-optimized) |
fmpfit_pywrap |
Auto dtype dispatch (single spectrum) |
fmpfit_f64_pywrap, fmpfit_f32_pywrap |
Single spectrum fitting |
fmpfit_block_pywrap |
Auto dtype dispatch (block fitting) |
fmpfit_f64_block_pywrap, fmpfit_f32_block_pywrap |
Block fitting |
MPFitResult |
Named tuple for fit results |
Common features: NaN handling, edge handling, optional center exclusion (fmedian/fsigma).
pip install . # Standard install
pip install -e . # Editable (development)
python setup.py build_ext --inplace # Build extensions onlyRequirements: Python 3.8+, NumPy ?1.20, C compiler. macOS Accelerate used when available.
import numpy as np
from ftools import fmedian, fsigma, fgaussian_f32, fgaussian_f64
# 2D/3D median and sigma filters
data = np.random.randn(100, 200)
median = fmedian(data, (3, 3), exclude_center=1)
sigma = fsigma(data, (3, 3), exclude_center=1)
# 3D works the same way
data_3d = np.random.randn(50, 100, 50)
median_3d = fmedian(data_3d, (3, 3, 3))
# Gaussian profiles
x = np.linspace(-10, 10, 1000, dtype=np.float32)
profile = fgaussian_f32(x, i0=1.0, mu=0.0, sigma=1.5)Single-spectrum fitting with auto dtype dispatch:
from ftools.fmpfit import fmpfit_pywrap
import numpy as np
x = np.linspace(-5, 5, 100)
y = 2.5 * np.exp(-0.5 * ((x - 1.0) / 0.8)**2) + np.random.randn(100) * 0.1
result = fmpfit_pywrap(
deviate_type=0, # Gaussian model
parinfo=[
{'value': 1.0, 'limits': [0.0, 10.0]}, # amplitude
{'value': 0.0, 'limits': [-5.0, 5.0]}, # mean
{'value': 1.0, 'limits': [0.1, 5.0]} # sigma
],
functkw={'x': x, 'y': y, 'error': np.ones_like(y) * 0.1}
)
print(f"Best-fit: {result.best_params}, ?²={result.bestnorm:.2f}")Block fitting (multiple spectra in one call, GIL-free):
from ftools.fmpfit import fmpfit_block_pywrap
import numpy as np
n_spectra, mpoints, npar = 100, 200, 3
x = np.tile(np.linspace(-5, 5, mpoints), (n_spectra, 1))
y = ... # shape (n_spectra, mpoints)
error = np.ones_like(y) * 0.1
p0 = np.tile([1.0, 0.0, 1.0], (n_spectra, 1))
bounds = np.array([[[0, 10], [-5, 5], [0.1, 5]]] * n_spectra)
results = fmpfit_block_pywrap(0, x, y, error, p0, bounds)
# results['best_params'] shape: (n_spectra, npar)fmedian(data, window_size, exclude_center=0)
fsigma(data, window_size, exclude_center=0)window_size:(x, y)or(x, y, z)? odd positive integersexclude_center: 1 to exclude center from calculation (useful for outlier detection)- Returns: float64 array, same shape as input
Computes: i0 * exp(-((x - mu)² / (2 * sigma²))
fgaussian_f32(x, i0, mu, sigma) # float32, fastest
fgaussian_f64(x, i0, mu, sigma) # float64Levenberg-Marquardt least-squares fitting. See src/ftools/fmpfit/README.md for details.
| Function | Description |
|---|---|
fmpfit_pywrap |
Auto dtype dispatch (single spectrum) |
fmpfit_f64_pywrap |
float64 single spectrum |
fmpfit_f32_pywrap |
float32 single spectrum |
fmpfit_block_pywrap |
Auto dtype dispatch (block of spectra) |
fmpfit_f64_block_pywrap |
float64 block fitting |
fmpfit_f32_block_pywrap |
float32 block fitting |
See examples/ directory for complete working examples.
pytest # Run all tests
pytest --cov=ftools --cov-report=html # With coverage| Module | Speedup vs NumPy | Notes |
|---|---|---|
| fgaussian_f32 | 5-10× | Accelerate vvexpf |
| fgaussian_f64 | 2-3× | Accelerate vvexp |
| fmedian/fsigma | ? | Sorting networks for small windows |
| fmpfit | ? | GIL-free, 4× speedup with 6 threads |
MIT
- Sorting networks: Bert Dobbelaere
- MPFIT: Craig Markwardt (cmpfit, MINPACK-1 derivative)