Add RL/RLGC deconvolution for 3D fluorescence - #573
Conversation
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
left a comment
There was a problem hiding this comment.
I think this looks good to me. Do we want to wait to merge, or just go ahead?
talonchandler
left a comment
There was a problem hiding this comment.
Thanks, left one comment to clean up the parametrization a bit. Otherwise I think we're close to ready.
| 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) |
There was a problem hiding this comment.
@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.
rlparameters only apply ifRLorRLGCis 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_modedoes. I'm guessing you can drop it for now.
Thanks!
There was a problem hiding this comment.
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.
Adds Richardson-Lucy (RL) and Gradient-Consensus (RLGC) deconvolution for 3D fluorescence.
Select it in a config with
reconstruction_algorithm: RLorRLGC, and tunerl_iterations,rl_background, andrl_stopping_tolerance. RLGC resists the noise overfitting ("starry night") that RL shows when over-iterated.RL/RLGC options raise
NotImplementedErrorfor 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 intests/models/test_rlgc.pycover the adjoint operators, bead sharpening under Poisson noise, RL vs RLGC over-iteration, and theNotImplementedguards.