Skip to content

Add Gaussian signal processing examples and runbook - #47

Closed
ernestow wants to merge 17 commits into
lume-science:mainfrom
ernestow:ernesto/gaussian-examples
Closed

Add Gaussian signal processing examples and runbook#47
ernestow wants to merge 17 commits into
lume-science:mainfrom
ernestow:ernesto/gaussian-examples

Conversation

@ernestow

@ernestow ernestow commented Aug 1, 2026

Copy link
Copy Markdown

Summary

Adds a Gaussian beam profile signal processing pipeline demonstrating lume-pva's core capabilities.

New Files

  • examples/gaussian_sim.py — Noisy Gaussian beam profile simulator (p4p direct)
  • examples/gaussian_classical.py — Classical denoiser using scipy curve_fit
  • examples/gaussian_train.py — Train PyTorch MLP for Gaussian parameter estimation
  • examples/gaussian_ml.py — ML-based denoiser using trained neural network
  • examples/lume-pva-runbook.md — Comprehensive getting-started guide

What These Demonstrate

  • Independent multi-process architecture (simulator + model as separate processes)
  • Remote PV subscription (continuous mode)
  • Classical vs ML approaches to the same problem
  • Side-by-side real-time comparison via EPICS PVs
  • The LUMEModel interface pattern with both scipy and PyTorch backends

How to Run

# Train the ML model (one-time, ~30s)
python examples/gaussian_train.py

# Start simulator
python examples/gaussian_sim.py

# Start classical denoiser (in another terminal)
python examples/gaussian_classical.py

# Start ML denoiser (in another terminal)
python examples/gaussian_ml.py

# Compare both against ground truth
pvmonitor SIM:mean est_mean ml_est_mean SIM:sigma est_sigma ml_est_sigma

JJL772 and others added 11 commits July 31, 2026 16:08
We do not need monotonic time here, and we are generally dealing with UNIX time everywhere else (including in p4p and pcaspy)
- gaussian_sim.py: Noisy Gaussian beam profile simulator (p4p direct)
- gaussian_classical.py: Classical denoiser using scipy curve_fit
- gaussian_train.py: Train PyTorch MLP for Gaussian parameter estimation
- gaussian_ml.py: ML-based denoiser using trained neural network
- lume-pva-runbook.md: Comprehensive getting-started guide

The Gaussian examples demonstrate:
- Independent multi-process architecture (simulator + model)
- Remote PV subscription (continuous mode)
- Classical vs ML approaches to the same problem
- Side-by-side real-time comparison via EPICS PVs
Two modes for PV ack'ing:
* immediate: Ack the pvput/caput request as soon as it's been inserted
  into the update queue.
* complete: Ack the pvput/caput request after the model is done
  simulating. Requires timeout changes on the client side for
  long-simulating models.

Also adds a model state PV that gets updated with the model's current
state.
@bhardwaj-gopika

Copy link
Copy Markdown
Contributor

I was able to get the examples running. I think it makes sense to remove some sections from the runbook - Part 2 Installation and configuring conda environment since software engineers are able to do that by themselves. The example are also a bit long and can be cleaned up.

@ernestow

ernestow commented Aug 5, 2026

Copy link
Copy Markdown
Author

@JJL772 — Ready for review whenever you get a chance.

JJL772 and others added 3 commits August 5, 2026 15:18
Merge pr-fix-put-timeouts: adds prefix CLI, put-mode, and STATUS PV
All PV names are now configurable at runtime:
- gaussian_sim.py: --pv-prefix (default: SIM:)
- gaussian_classical.py: --pv-prefix (default: example:) + --sim-prefix (default: SIM:)
- gaussian_ml.py: --pv-prefix (default: example:) + --sim-prefix (default: SIM:)

No more hardcoded PV names. Multiple instances can run simultaneously
with different prefixes. Uses add_common_test_args from upstream.
@JJL772

JJL772 commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

This will be merged after #40

Comment on lines +33 to +47
"""
Classical denoiser: estimates Gaussian parameters from noisy signal
using nonlinear least-squares curve fitting.

Inputs:
- noisy_signal (256-point array from simulator)
- x_axis (256-point array from simulator)

Outputs:
- est_mean (estimated center position)
- est_sigma (estimated width)
- est_amplitude (estimated peak height)
- denoised_signal (reconstructed clean Gaussian from fit)
- fit_quality (R-squared goodness of fit, 0 to 1)
"""

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please follow the syntax guidelines for docstrings (See runner.py for the syntax; I believe it's Google-style docstrings or something)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

whoops- thanks for clarifying. I always get these mixed up

Comment thread examples/gaussian_ml.py
Comment on lines +209 to +219
"""
╔══════════════════════════════════════════════════════════════╗
║ NEURAL NETWORK INFERENCE ║
║ ║
║ Instead of curve_fit (iterative optimization, ~2ms), ║
║ we do ONE forward pass through a trained network (~0.1ms). ║
║ ║
║ The network has already "memorized" the mapping from ║
║ noisy signals to parameters during training. ║
╚══════════════════════════════════════════════════════════════╝
"""

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same thing: Please follow the docstring format

- start-all.sh: launches all 5 servers with verification
- Individual run-*.sh scripts for each server
- Includes EPICS env setup (suppresses CA beacon warnings)
- Self-documenting: prints PV names, prefixes, and demo commands
@tangkong

tangkong commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

This should reference pr-fix-put-timeouts as its base branch. github added stacks recently and I've enjoyed using them

@tangkong tangkong left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this being added to lume-pva? This looks like an exercise in basic machine learning, rather than demonstrating capabilities of lume-pva.

This should probably be distilled into an example of how to configure monitoring of remote PVs, without all the machine learning machinery.

from typing import Any

import numpy as np
from scipy.optimize import curve_fit

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't currently installed. If you really want to support it, it should be added to the dev dependencies

Comment on lines +33 to +47
"""
Classical denoiser: estimates Gaussian parameters from noisy signal
using nonlinear least-squares curve fitting.

Inputs:
- noisy_signal (256-point array from simulator)
- x_axis (256-point array from simulator)

Outputs:
- est_mean (estimated center position)
- est_sigma (estimated width)
- est_amplitude (estimated peak height)
- denoised_signal (reconstructed clean Gaussian from fit)
- fit_quality (R-squared goodness of fit, 0 to 1)
"""

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


tmux kill-session -t $SESSION 2>/dev/null
tmux new-session -d -s $SESSION
tmux send-keys -t $SESSION "conda activate lume-pva && source $ENVSCRIPT && cd $SRCDIR && python -m examples.math_model --pv-prefix '$PREFIX' --put-mode $PUT_MODE" Enter

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tmux is not installed in every environment by default, and this script makes many assumptions about the environment this is being run in.

This type of script isn't really appropriate to package with lume-pva. It belongs external to this repository, at best

- examples/__init__.py: add --pv-server-protocol CLI flag (default: ca pva)
- gaussian_classical.py, gaussian_ml.py: wire flag into Runner config
- run-gauss-*.sh: use PVA-only mode, source epics-env-localhost.sh
- start-all-pva.sh: launch 3 gaussian servers in PVA-only mode
- epics-env-localhost.sh: EPICS env for local development

When --pv-server-protocol pva is set, Runner skips pcaspy entirely.
Zero CA listeners. Clients use pvxget/pvxput/pvxmonitor.
pvua client side (subscribing to remote PVs) is unaffected.
@JJL772

JJL772 commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

After talking with Ernest, he decided that this PR belongs in a separate sandbox, since there are already some smaller examples here.

@JJL772 JJL772 closed this Aug 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants