Skip to content

Implement FitResult dataclass for unified solver diagnostics #205

@darksim33

Description

@darksim33

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:

  1. Create FitResult dataclass in src/pyneapple/solvers/
  2. Update CurveFitSolver.fit() to return FitResult
  3. Update NNLSSolver.fit() to return FitResult
  4. Update ConstrainedCurveFitSolver.fit() to return FitResult
  5. Update fitters to handle FitResult properly
  6. Add tests for failure detection

Metadata

Metadata

Assignees

No one assigned

    Labels

    diagnosticsIssues related to solver returned diagnostics and their handlingenhancementNew feature or requestsolverSolver Related Issues

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions