Skip to main content

A flexible template for fitting SANS data with SasModels

Project description

SANS Model Fitter

Tests Docs codecov

A flexible, model-agnostic Python template for fitting Small-Angle Neutron Scattering (SANS) data using the SasModels library.

Features

  • Model-Agnostic Design: Works with any model from the SasModels library (cylinder, sphere, core_shell, etc.)
  • Multiple Fitting Engines: Supports both BUMPS (default) and LMFit optimization engines
  • Flexible Data Loading: Reads CSV, XML, and HDF5 formats via sasdata
  • User-Friendly Parameter Management: Easy-to-use interface for setting parameter values, bounds, and fitting flags
  • Comprehensive Visualization: Automatic plotting of data, fitted model, and residuals
  • Result Export: Save fitted parameters and curves to CSV files

Installation

Option 1: Using pip (recommended for users)

# Clone the repository
git clone https://github.com/ai4se1dk/SANS-fitter.git
cd SANS-fitter

# Install the package
pip install -e .

# Or install with development dependencies
pip install -e ".[dev]"

Option 2: Using Pixi (recommended for development)

# Clone the repository
git clone https://github.com/ai4se1dk/SANS-fitter.git
cd SANS-fitter

# Install dependencies with Pixi
pixi install

# Run tests
pixi run test

# Run demo notebook
pixi run run-demo

Quick Start

from sans_fitter import SANSFitter

# Create fitter instance
fitter = SANSFitter()

# Load your data
fitter.load_data('my_sans_data.csv')

# Set the model (any model from SasModels!)
fitter.set_model('cylinder')

# View initial parameter values
fitter.get_params()

# Configure parameters for fitting
fitter.set_param('radius', value=20, min=1, max=100, vary=True)
fitter.set_param('length', value=400, min=10, max=1000, vary=True)
fitter.set_param('scale', value=0.1, min=0, max=1, vary=True)
fitter.set_param('background', value=0.01, min=0, max=1, vary=True)

# View current parameters
fitter.get_params()

# Perform the fit (using BUMPS by default)
result = fitter.fit(engine='bumps', method='amoeba')

# Visualize results
fitter.plot_results(show_residuals=True)

# Save results
fitter.save_results('fit_results.csv')

Switching Models

The fitter is completely model-agnostic. Simply load a different model:

# Try with a sphere model instead
fitter.set_model('sphere')
fitter.get_params()  # See different parameters!

fitter.set_param('radius', value=25, min=5, max=100, vary=True)
result = fitter.fit()

Switching Fitting Engines

# Use BUMPS (default)
result = fitter.fit(engine='bumps', method='amoeba')

# Or use LMFit
result = fitter.fit(engine='lmfit', method='leastsq')

Working with Structure Factors

Combine any SasModels form factor with an interaction model to capture correlated systems.

fitter.set_model('sphere')

# Apply a structure factor (creates sphere@hardsphere product model)
fitter.set_structure_factor('hardsphere', radius_effective_mode='link_radius')

# Inspect linked parameters and run the fit as usual
fitter.get_params()
result = fitter.fit()

# Remove the structure factor to go back to the pure form factor
fitter.remove_structure_factor()
  • Supported structure factors: hardsphere, hayter_msa, squarewell, stickyhardsphere.
  • Radius handling: use radius_effective_mode='link_radius' to keep radius_effective equal to the form-factor radius, or leave the default unconstrained to fit it independently.
  • State helpers: get_structure_factor() returns the active structure factor so notebooks/scripts can branch as needed.

Available Methods

BUMPS methods:

  • 'amoeba' - Nelder-Mead simplex (default, robust)
  • 'lm' - Levenberg-Marquardt
  • 'newton' - Newton's method
  • 'de' - Differential evolution

LMFit methods:

  • 'leastsq' - Levenberg-Marquardt (default)
  • 'least_squares' - Trust Region Reflective
  • 'differential_evolution' - Global optimizer
  • 'powell', 'nelder', etc.

Demo Notebook

See sans_fitter_demo.ipynb for a comprehensive demonstration with examples.

Design Philosophy

This implementation follows a template pattern where:

  1. The core fitting logic is abstracted into a reusable class
  2. Models are loaded dynamically from SasModels - no hardcoded model assumptions
  3. Parameters are discovered automatically from the model definition
  4. Multiple optimization engines are supported through a unified interface
  5. The user maintains full control over parameter initialization and bounds

Implementation Details

Engine Adapters

The fitter implements adapter patterns for both BUMPS and LMFit:

  • BUMPS: Uses native sasmodels.bumps_model integration
  • LMFit: Uses sasmodels.direct_model.DirectModel with a custom residual function

Parameter Management

Parameters are stored internally with:

  • value: Current/initial value
  • min, max: Bounds
  • vary: Fitting flag
  • description: From model metadata

This allows the fitter to work with any model without prior knowledge of its parameters.

Web Application

A Streamlit-based web application is now available for interactive SANS data analysis with a user-friendly interface!

Features

  • 📤 Data Upload: Upload your SANS datasets (CSV or .dat files)
  • 🤖 AI-Assisted Model Selection: Get intelligent model suggestions based on your data
  • 🎯 Manual Model Selection: Choose from all available SasModels
  • ⚙️ Interactive Parameter Tuning: Adjust parameters with real-time UI controls
  • 📊 Interactive Plots: Visualize data and fits with Plotly's zoom, pan, and export features
  • 💾 Export Results: Save fitted parameters and curves to CSV

Quick Start (Web App)

# Install web application dependencies
pip install -e ".[web]"

# Run the Streamlit app
streamlit run app.py

The app will open in your browser at http://localhost:8501.

Using the Web Application

  1. Upload Data: Use the sidebar to upload your SANS data file (CSV or .dat format with Q, I, dI columns) or load the example dataset
  2. Select Model:
    • Manual: Choose from dropdown of all SasModels models
    • AI-Assisted: Optionally provide an OpenAI API key for AI-powered suggestions, or use built-in heuristics
  3. Configure Parameters: Set initial values, bounds, and which parameters to fit
  4. Run Fit: Choose optimization engine (BUMPS or LMFit) and method, then click "Run Fit"
  5. View Results: Interactive plots show data with error bars and fitted curve
  6. Export: Download fitted parameters as CSV

Web App Deployment

Streamlit Cloud

  1. Push this repository to GitHub
  2. Go to share.streamlit.io
  3. Connect your GitHub account and deploy from the repository
  4. Set app.py as the main file

Heroku

# Create Procfile
echo "web: streamlit run app.py --server.port=$PORT --server.address=0.0.0.0" > Procfile

# Deploy
heroku create your-app-name
git push heroku main

Docker

# Build image
docker build -t sans-fitter-app .

# Run container
docker run -p 8501:8501 sans-fitter-app

API Integration

The web app supports optional AI-powered model suggestions via the OpenAI API:

  1. Get an API key from platform.openai.com
  2. Enter the key in the sidebar when using AI-Assisted mode
  3. Or set as environment variable: export OPENAI_API_KEY=your-key-here

Note: The app also works without an API key using built-in heuristic suggestions.

License

BSD 3-Clause License. See LICENSE for the full text.

References

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

sans_fitter-0.0.1.tar.gz (20.9 kB view details)

Uploaded Source

Built Distribution

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

sans_fitter-0.0.1-py3-none-any.whl (13.0 kB view details)

Uploaded Python 3

File details

Details for the file sans_fitter-0.0.1.tar.gz.

File metadata

  • Download URL: sans_fitter-0.0.1.tar.gz
  • Upload date:
  • Size: 20.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for sans_fitter-0.0.1.tar.gz
Algorithm Hash digest
SHA256 437f3ecec347601dc60fbab1bdd098d9d19fcb0ba93fa7424dd65053bd0be15f
MD5 3ca6c3e42867ba8193912e14da299fc8
BLAKE2b-256 6124a223a8523b43dcffff7db410dcf5302918ae7a636cdc561e4d2c2ce92ca3

See more details on using hashes here.

Provenance

The following attestation bundles were made for sans_fitter-0.0.1.tar.gz:

Publisher: ci.yml on ai4se1dk/SANS-fitter

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file sans_fitter-0.0.1-py3-none-any.whl.

File metadata

  • Download URL: sans_fitter-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 13.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for sans_fitter-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 66357cabc3f510ae283915dcd1141fd5a32f3906418c56f23e883314562d20d4
MD5 78054229d716394678b4bbde743f3a8f
BLAKE2b-256 abdeee1443e51fffed14653abd403ebd3e6e7324e62cd3b6a9658f3a6c64f5e3

See more details on using hashes here.

Provenance

The following attestation bundles were made for sans_fitter-0.0.1-py3-none-any.whl:

Publisher: ci.yml on ai4se1dk/SANS-fitter

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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