Skip to content

Add RL/RLGC deconvolution for 3D fluorescence - #573

Open
talonchandler wants to merge 7 commits into
mainfrom
rl-rlgc
Open

Add RL/RLGC deconvolution for 3D fluorescence#573
talonchandler wants to merge 7 commits into
mainfrom
rl-rlgc

Conversation

@talonchandler

@talonchandler talonchandler commented Aug 3, 2026

Copy link
Copy Markdown
Collaborator

Adds Richardson-Lucy (RL) and Gradient-Consensus (RLGC) deconvolution for 3D fluorescence.

Select it in a config with reconstruction_algorithm: RL or RLGC, and tune rl_iterations, rl_background, and rl_stopping_tolerance. RLGC resists the noise overfitting ("starry night") that RL shows when over-iterated.

RL/RLGC options raise NotImplementedError for 2D fluorescence and for phase/birefringence.

The operator-agnostic solver lives in waveorder/rlgc.py, adapted from Andrew York's Gradient Consensus demo (doi.org/10.5281/zenodo.10278918). Tests in tests/models/test_rlgc.py cover the adjoint operators, bead sharpening under Poisson noise, RL vs RLGC over-iteration, and the NotImplemented guards.

@talonchandler
talonchandler marked this pull request as ready for review August 3, 2026 22:24
@talonchandler
talonchandler requested a review from srivarra as a code owner August 3, 2026 22:24
talonchandler and others added 6 commits August 4, 2026 10:20
Signed-off-by: Sricharan Reddy Varra <sricharan.varra@biohub.org>
Eq. 28 returns a spectral amplitude at the cutoff, which is beta's
scale. alpha is added to |OTF|**2, so substituting the same value
leaves it ~200x too large.

On a confocal OTF with |H(cutoff)| = 0.0106 the Wiener spectral
product at the cutoff was 0.0053 instead of 0.171, i.e. ~187
iterations to converge the finest frequencies rather than ~6 --
defeating the point of an unmatched back projector.
calculate_back_projector depends only on the OTF and the rl_bp_*
knobs, all fixed for a run, but sat inside
apply_inverse_transfer_function and so rebuilt on every call.
Callers reconstructing many tiles can now build it once.

Output is bit-identical; matched is unaffected.
Signed-off-by: Sricharan Reddy Varra <sricharan.varra@biohub.org>

@srivarra srivarra left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think this looks good to me. Do we want to wait to merge, or just go ahead?

@talonchandler talonchandler left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Thanks, left one comment to clean up the parametrization a bit. Otherwise I think we're close to ready.

Comment on lines +22 to +29
rl_iterations: 25 # maximum RL / RLGC iterations
rl_background: 0.0 # constant background folded into the RL / RLGC Poisson forward model
rl_stopping_tolerance: null # relative-change early-stop threshold for RL / RLGC (null = run all iterations)
rl_back_projector: matched # 'matched' is the matched transpose (classic RL); the unmatched 'gaussian'/'butterworth'/'wiener'/'wiener_butterworth' converge in far fewer iterations but are supported for 'RL' only, not 'RLGC'
rl_bp_alpha: null # Wiener regularization for the 'wiener'/'wiener_butterworth' back projectors (null = matched cutoff gain)
rl_bp_beta: null # cutoff gain for the 'butterworth'/'wiener_butterworth' back projectors (null = matched cutoff gain)
rl_bp_order: 8 # Butterworth order for the 'butterworth'/'wiener_butterworth' back projectors
rl_bp_resolution_mode: fwhm # cutoff-frequency rule for the back projector ('fwhm_over_sqrt2' suits iSIM)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

@srivarra can we think of a way to clean up these configs a bit? I'm okay if there are lots of parameters in the lower-level methods, but I'd prefer to keep the user-facing configs as clean as we can. If we're not careful this list will get very long very fast.

  • is there a reasonable way to nest these parameters? For example, regularization strength only applies if 'Tikhonov' mode is being used. rl parameters only apply if RL or RLGC is being used.
  • Have you found it useful to play with rl_bp_order? If not, you can leave it off of the config for now.
  • I'm not sure with rl_bp_resolution_mode does. I'm guessing you can drop it for now.

Thanks!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

yeah they're pretty messy. I think a solution is to create another Pydantic settings object specifically for RL, and we can set it to be optional for the fluorescence reconstruction yaml configuration.

I'm going to play with this and let you know if it's useful or not. It's the exponent of the butterworth and so we'll just leave it out.

rl_bp_resolution_mode helps the butterworth and weiener-butterworth know where the resolution limit is. It's measured from the OTF, but you can pick the rule for tuning the measurement into a cutoff. It's either the full width at half maximum or that divided by sqrt(2). Either way, I think we can drop this parameter as well for the config.

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.

2 participants