Skip to main content

Real-time laser beam profiler with Gaussian fitting for GenICam cameras

Project description

pyBeamprofiler

Real-time laser beam profiler with Gaussian fitting for GenICam cameras.

Python 3.10–3.14 License: MIT

Features

  • Fast Gaussian fitting: 850+ fps for 1D, 95 fps for 2D
  • Live streaming: Dash web interface (10 Hz) or Jupyter notebooks (6-10 Hz)
  • Multiple fitting methods: 1D projections, 2D Gaussian, linecut
  • Multiple width definitions: Gaussian (1/e²), FWHM, D4σ (ISO 11146)
  • Interactive controls: Jupyter widgets for camera settings
  • Flexible inputs: Static images or camera streams
  • Hardware support: FLIR, Basler cameras via GenICam/Harvesters
  • Simulated camera: Included for testing without hardware
  • Auto-configuration: Pixel size detection, auto-exposure/gain disabled by default
  • ROI support: Region of Interest with full sensor default

Quick Start

# Install (creates/updates a reproducible environment from the lockfile)
uv sync

# Run with simulated camera (no hardware needed)
uv run pybeamprofiler --camera simulated

# Browser opens automatically at http://127.0.0.1:8050

Installation

Basic Installation

uv sync

uv sync installs the exact versions recorded in uv.lock, giving you a reproducible environment. This is the recommended path for both users and CI.

Installing into an existing environment? If you are managing your own virtualenv or conda environment and do not want to use the lockfile, you can run uv pip install . (or plain pip install .) instead. Be aware that this resolves dependencies independently and may produce a different set of package versions than the lockfile.

Development Installation

uv sync --extra dev
pre-commit install  # Optional: enable git hooks

Optional Dependencies

uv sync --extra matplotlib  # Matplotlib fallback for CLI
uv sync --extra test        # Testing tools only
uv sync --extra dev         # All development tools

Usage

Command Line Interface

# Simulated camera (no hardware needed)
pybeamprofiler --camera simulated

# Real cameras (requires SDK installation)
pybeamprofiler --camera flir    # FLIR/Spinnaker
pybeamprofiler --camera basler  # Basler/Pylon

# Single shot acquisition
pybeamprofiler --num-img 1

# Static image analysis
pybeamprofiler --file beam.png

# Custom fitting and definitions
pybeamprofiler --fit 2d --definition fwhm

# Set exposure time (in seconds)
pybeamprofiler --exposure-time 0.05

# Fast display mode (heatmap only)
pybeamprofiler --heatmap-only

# See all options
pybeamprofiler --help

Tip: If you installed via uv sync, prefix commands with uv run (e.g., uv run pybeamprofiler --help). You can also use python -m pybeamprofiler as an alternative.

Continuous streaming automatically opens a browser with live beam profile and fitting results at http://127.0.0.1:8050.

Python API

Basic Usage

from pybeamprofiler import BeamProfiler

# Initialize with simulated camera
bp = BeamProfiler(camera="simulated")
bp.plot()  # Opens Dash web interface

# For real hardware
bp = BeamProfiler(camera="flir")      # or camera="basler"
bp.plot()

Single Measurement

from pybeamprofiler import BeamProfiler

bp = BeamProfiler(camera="simulated")
bp.plot(num_img=1)

# Access results
print(f"Beam width: {bp.width:.1f} μm")
print(f"Width X: {bp.width_x:.1f} μm, Y: {bp.width_y:.1f} μm")
print(f"Center: ({bp.center_x:.1f}, {bp.center_y:.1f}) pixels")
print(f"Peak intensity: {bp.peak_value:.0f}")

Static Image Analysis

from pybeamprofiler import BeamProfiler

bp = BeamProfiler(file="beam_image.png")
bp.plot(num_img=1)

print(f"Width X: {bp.width_x:.1f} μm")
print(f"Width Y: {bp.width_y:.1f} μm")

Camera Control

# List available cameras
from pybeamprofiler import print_camera_info
print_camera_info()

# Set exposure time (three ways)
bp = BeamProfiler(camera="simulated", exposure_time=0.05)  # 1. During init

bp.exposure_time = 0.01  # 2. Direct attribute

bp.setting(exposure_time=0.05)  # 3. Via setting() method

# Set multiple parameters
bp.setting(
    exposure_time=0.025,
    Gain=10.0,
    ExposureAuto=False,
    GammaEnable=False
)

# Interactive widget (Jupyter only)
bp.setting()  # Opens interactive control panel

Fitting Methods

# 1D Gaussian fitting (fastest, 850+ fps)
bp.fit_method = '1d'
bp.plot(num_img=1)

# 2D Gaussian fitting with rotation
bp.fit_method = '2d'
bp.plot(num_img=1)
print(f"Rotation angle: {bp.angle_deg:.1f}°")

# Linecut through peak
bp.fit_method = 'linecut'
bp.plot(num_img=1)

Width Definitions

# Gaussian (1/e²) - standard laser beam width
bp.definition = 'gaussian'
bp.plot(num_img=1)

# Full Width at Half Maximum
bp.definition = 'fwhm'
bp.plot(num_img=1)

# D4σ (ISO 11146 second moment)
bp.definition = 'd4s'
bp.plot(num_img=1)

# Access all width metrics
print(f"1/e² width: {bp.fw_1e2_x:.1f} μm")
print(f"FWHM: {bp.fwhm_x:.1f} μm")

Region of Interest (ROI)

# Get ROI info
roi = bp.camera.roi_info
print(f"ROI: {roi['width']}×{roi['height']} at ({roi['offset_x']}, {roi['offset_y']})")

# Set ROI (GenICam cameras only)
bp.camera.set_roi(offset_x=100, offset_y=100, width=800, height=600)

# Reset to full sensor
bp.camera.set_roi(offset_x=0, offset_y=0, width=None, height=None)

Jupyter Notebook

pyBeamprofiler works natively in Jupyter notebooks with interactive widgets:

  • Camera discovery and initialization
  • Interactive controls with widgets (bp.setting())
  • Single-shot and continuous acquisition
  • Multiple fitting methods and width definitions
  • Programmatic camera control

Hardware Setup

FLIR Cameras (Spinnaker SDK)

macOS/Linux:

# Install Spinnaker SDK from FLIR website
# Then set environment variable
export GENICAM_GENTL64_PATH=/usr/local/lib/spinnaker-gentl

Windows:

set GENICAM_GENTL64_PATH=C:\Program Files\FLIR Systems\Spinnaker\cti64\vs2015

Basler Cameras (Pylon SDK)

macOS:

export GENICAM_GENTL64_PATH=/Library/Frameworks/pylon.framework/Libraries/gentlproducer/gtl

Linux:

export GENICAM_GENTL64_PATH=/opt/pylon/lib64/gentlproducer/gtl

Windows:

set GENICAM_GENTL64_PATH=C:\Program Files\Basler\pylon\Runtime\x64

Note: GenICam cameras can only be accessed by one application at a time. Close other camera software before using pyBeamprofiler.

Supported Cameras

FLIR

  • Blackfly S (BFS-PGE, BFS-U3, etc.)
  • Grasshopper3 (GS3)
  • Auto-detected sensors: Sony IMX273, IMX174, IMX183, IMX250, IMX252, etc.

Basler

  • ace (acA series) - USB3, GigE
  • ace 2 (a2A series)
  • Auto-detected sensors: Sony IMX253, IMX226, IMX249, IMX255, etc.

Pixel Size Auto-Detection

Automatic pixel size detection for 40+ sensor models including:

  • Sony IMX series (IMX174, IMX183, IMX226, IMX249, IMX250, IMX252, IMX253, IMX255, IMX264, IMX265, IMX273, IMX287, IMX290, IMX291, IMX304, IMX392, IMX412, IMX477, IMX485, IMX530, IMX531, IMX540, IMX541, IMX542, IMX547)
  • Direct Basler model lookups (acA4024-8gm, acA4024-29um, acA1920-155um, acA2440-75um, acA3800-14um)

Performance

  • Gaussian fitting: 850+ fps (1D), 95 fps (2D) - Not the bottleneck!
  • Display rates:
    • Jupyter notebook: 6-10 Hz (standard), 25-30 Hz (heatmap only)
    • Dash web interface: 10 Hz
    • Matplotlib fallback: ~5 Hz

Dependencies

Core:

  • numpy, scipy - Numerical computing and optimization
  • plotly, dash - Interactive visualization and web interface
  • ipywidgets - Jupyter notebook controls
  • Pillow - Image file loading
  • harvesters - GenICam camera interface

Optional:

  • matplotlib - Fallback plotting (CLI only)

Development:

  • pytest, pytest-cov - Testing framework
  • ruff - Fast linter and formatter
  • ty - Static type checking
  • pre-commit - Git hooks for code quality

Testing

# Run all tests (coverage is enabled by default via pyproject.toml)
uv run pytest

# Run with HTML coverage report
uv run pytest --cov-report=html

# Run specific test file
uv run pytest tests/test_fitting.py -v

Development

# Install in development mode
uv sync --extra dev

# Install pre-commit hooks
pre-commit install

# Run linter
uv run ruff check src tests

# Run formatter
uv run ruff format src tests

# Run type checker
uv run ty check src tests

Troubleshooting

Camera Not Found

  1. Check SDK installation:

  2. Set GENICAM_GENTL64_PATH:

    export GENICAM_GENTL64_PATH=/path/to/cti/files
    
  3. Check camera connection:

    from pybeamprofiler import print_camera_info
    print_camera_info()  # Lists all detected cameras
    
  4. Access denied error:

    • Close other camera software (Spinnaker GUI, Pylon Viewer, etc.)
    • GenICam cameras allow only one connection at a time

GigE vs USB3

  • Basler cameras: Code auto-detects and prefers GigE over USB3
  • For USB3 cameras, explicitly pass the USB3 CTI file path:
    from pybeamprofiler.basler import BaslerCamera
    cam = BaslerCamera(cti_file="/path/to/ProducerU3V.cti")
    

Jupyter Kernel Restart

When re-initializing cameras in Jupyter, restart the kernel first:

  • Kernel → Restart Kernel
  • This releases the camera hardware lock

License

MIT License - see LICENSE file for details.

Author

C.-A. Chen (acechen@cirx.org)

Contributing

Contributions welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new functionality
  4. Ensure all tests pass: uv run pytest
  5. Run code quality checks: uv run ruff check src tests and uv run ruff format src tests
  6. Submit a pull request

Acknowledgments

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

pybeamprofiler-0.0.1.tar.gz (183.8 kB view details)

Uploaded Source

Built Distribution

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

pybeamprofiler-0.0.1-py3-none-any.whl (38.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: pybeamprofiler-0.0.1.tar.gz
  • Upload date:
  • Size: 183.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for pybeamprofiler-0.0.1.tar.gz
Algorithm Hash digest
SHA256 88941d88998393b7035a125c00c611702f66fec96d9907da1f18face50c1e43a
MD5 2f5805fdf0fcdf6d834f2e185b443cf5
BLAKE2b-256 4c1aa277bf697f5e7d88d97b4eab806312a6ecddc2df48953377e6df09c7bfca

See more details on using hashes here.

File details

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

File metadata

  • Download URL: pybeamprofiler-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 38.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for pybeamprofiler-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 a91d12603fc8f8506b965730f4499d83b230cabb6e69f05c804003eb10c98a35
MD5 ce4f2ddb3a6123f101c0e6bba171dcba
BLAKE2b-256 fc40d8aecb28a86107581906bbbe8c2596be76d07cd8b3f2dc3fb309248b1a24

See more details on using hashes here.

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