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.
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 plainpip 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 withuv run(e.g.,uv run pybeamprofiler --help). You can also usepython -m pybeamprofileras 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
-
Check SDK installation:
- FLIR: Install Spinnaker SDK
- Basler: Install Pylon SDK
-
Set GENICAM_GENTL64_PATH:
export GENICAM_GENTL64_PATH=/path/to/cti/files
-
Check camera connection:
from pybeamprofiler import print_camera_info print_camera_info() # Lists all detected cameras
-
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:
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass:
uv run pytest - Run code quality checks:
uv run ruff check src testsanduv run ruff format src tests - Submit a pull request
Acknowledgments
- Built on Harvesters for GenICam camera interface
- Uses Plotly/Dash for interactive visualization
- Inspired by various beam profiling tools: LaseView (old freeware version), ptomato/Beams, jordens/bullseye
- FLIR and Basler cameras loaned from Atom Computing for testing
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
88941d88998393b7035a125c00c611702f66fec96d9907da1f18face50c1e43a
|
|
| MD5 |
2f5805fdf0fcdf6d834f2e185b443cf5
|
|
| BLAKE2b-256 |
4c1aa277bf697f5e7d88d97b4eab806312a6ecddc2df48953377e6df09c7bfca
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a91d12603fc8f8506b965730f4499d83b230cabb6e69f05c804003eb10c98a35
|
|
| MD5 |
ce4f2ddb3a6123f101c0e6bba171dcba
|
|
| BLAKE2b-256 |
fc40d8aecb28a86107581906bbbe8c2596be76d07cd8b3f2dc3fb309248b1a24
|