Description
Currently, when curve fitting fails in our solvers (CurveFitSolver, NNLSSolver, ConstrainedCurveFitSolver), the exception is caught silently and initial parameter guesses are returned as if the fit succeeded. This makes it impossible for downstream code to distinguish between converged and failed fits.
Example of the current problem:
In curvefit.py _fit_single_pixel (lines 313-317)
except Exception as e:
logger.warning(f"Fit failed for pixel {pixel_idx}: {e}")
return p0, np.full((len(p0), len(p0)), np.nan)`
Callers cannot detect whether:
- The fit actually succeeded
- The fit failed due to numerical issues
- The fit exceeded max iterations
Proposed Solution:
Introduce a FitResult dataclass (similar to scipy.optimize.OptimizeResult) that provides structured diagnostic information:
from dataclasses import dataclass
import numpy as np
@dataclass
class FitResult:
"""Result of a curve fitting operation."""
params: np.ndarray
covariance: np.ndarray | None = None
success: bool = True
error: str | None = None
n_iterations: int | None = None
message: str | None = None
Benefits:
- Backwards compatible - existing code continues to work
- Aligns with scikit-learn estimator patterns
- Allows users to handle failures explicitly
- Provides actionable error messages for debugging
Tasks:
- Create FitResult dataclass in src/pyneapple/solvers/
- Update CurveFitSolver.fit() to return FitResult
- Update NNLSSolver.fit() to return FitResult
- Update ConstrainedCurveFitSolver.fit() to return FitResult
- Update fitters to handle FitResult properly
- Add tests for failure detection
Description
Currently, when curve fitting fails in our solvers (CurveFitSolver, NNLSSolver, ConstrainedCurveFitSolver), the exception is caught silently and initial parameter guesses are returned as if the fit succeeded. This makes it impossible for downstream code to distinguish between converged and failed fits.
Example of the current problem:
Callers cannot detect whether:
Proposed Solution:
Introduce a FitResult dataclass (similar to scipy.optimize.OptimizeResult) that provides structured diagnostic information:
Benefits:
Tasks: