sci-find-peaks 0.1.0

A Rust port of SciPy's find_peaks function, designed to match SciPy's behavior exactly.
Documentation
import numpy as np
import pandas as pd
from scipy.signal import find_peaks
import json

def generate_complex_signal():
    x = np.linspace(0, 100, 1000)
    # Background curve
    y = np.sin(x * 0.1) * 5
    
    # Sharp peaks
    y += np.exp(-((x - 20)**2) / 2) * 10
    y += np.exp(-((x - 50)**2) / 0.5) * 8 # Narrow
    
    # Plateau
    y[300:320] = 8.0 
    
    # Negative peaks (valleys in absolute terms)
    y -= np.exp(-((x - 70)**2) / 5) * 5
    
    # Noise
    np.random.seed(42)
    y += np.random.normal(0, 0.1, 1000)
    
    return y

def run_test_case(name, y, **kwargs):
    peaks, props = find_peaks(y, **kwargs)
    
    # Convert numpy arrays to lists for JSON serialization
    serializable_props = {k: v.tolist() for k, v in props.items()}
    
    result = {
        "name": name,
        "parameters": kwargs,
        "input_data": y.tolist(),
        "expected_peaks": peaks.tolist(),
        "expected_properties": serializable_props
    }
    return result

def main():
    y = generate_complex_signal()
    
    results = []
    
    # Case 1: Simple Local Maxima
    results.append(run_test_case("simple", y))
    
    # Case 2: Height filter
    results.append(run_test_case("height", y, height=5.0))
    
    # Case 3: Prominence
    results.append(run_test_case("prominence", y, prominence=1.0))
    
    # Case 4: Width + Prominence
    results.append(run_test_case("width", y, width=2.0, prominence=0.5, rel_height=0.75))
    
    # Case 5: Distance
    results.append(run_test_case("distance", y, distance=20))
    
    # Case 6: Threshold
    results.append(run_test_case("threshold", y, threshold=0.1))

    # Case 7: Plateau
    # Create specific plateau signal
    y_plat = np.zeros(100)
    y_plat[20:30] = 5
    y_plat[50:55] = 10 # shorter plateau
    y_plat += np.random.normal(0, 0.01, 100)
    results.append(run_test_case("plateau", y_plat, plateau_size=2))

    with open("test_data.json", "w") as f:
        json.dump(results, f, indent=2)
        
    print("Generated test_data.json")

if __name__ == "__main__":
    main()