feat(fluo): FISTA (non-negative) reconstruction for 3D fluorescence#563
Draft
talonchandler wants to merge 1 commit into
Draft
feat(fluo): FISTA (non-negative) reconstruction for 3D fluorescence#563talonchandler wants to merge 1 commit into
talonchandler wants to merge 1 commit into
Conversation
Adds reconstruction_algorithm: FISTA as a third option (alongside
Tikhonov and TV) for 3D fluorescence reconstructions. FISTA solves
min 0.5 ||Hx - y||^2 + 0.5 lambda ||x||^2 s.t. x >= 0
via accelerated proximal gradient with a ReLU prox, guaranteeing a
non-negative reconstruction. Shares regularization_strength with
Tikhonov.
Why: TLS reconstructions on dynacell (mantis A549 SEC61, hummingbird
A549 G3BP1) produce ~50 percent non-physical negative voxels regardless
of regularization choice. FISTA removes the negatives at the cost of
extra iterations (~30-100x TLS wall time for ~100 iters).
Changes:
- waveorder/api/fluorescence.py: new ApplyInverseSettings subclass of
FourierApplyInverseSettings widens the algorithm Literal to include
FISTA and adds FISTA_max_iter / FISTA_rel_change_tol. 2D fluorescence
raises NotImplementedError for FISTA (singular-system path doesn't
yet support it).
- waveorder/models/isotropic_fluorescent_thick_3d.py: adds the FISTA
branch with constant step size 1/L where L = max(|OTF|^2) + lambda.
Same FFT pair count as Tikhonov per iteration; early-stop on
relative change.
Example config: benchmarks/configs/fluor_3d_beads_fista.yml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
reconstruction_algorithm: FISTAto 3D fluorescence reconstructions. FISTA solves```
min 0.5 ||Hx - y||^2 + 0.5 lambda ||x||^2 s.t. x >= 0
```
via accelerated proximal gradient with a ReLU prox at every iteration, guaranteeing a non-negative reconstruction. Shares
regularization_strengthwith the existing Tikhonov path.Config example
```yaml
reconstruction_dimension: 3
input_channel_names: [GFP]
fluorescence:
transfer_function:
yx_pixel_size: 0.1
z_pixel_size: 0.25
wavelength_emission: 0.532
index_of_refraction_media: 1.3
numerical_aperture_detection: 1.2
apply_inverse:
reconstruction_algorithm: FISTA # NEW
regularization_strength: 5.0e-3 # shared L2 with Tikhonov
FISTA_max_iter: 100 # NEW
FISTA_rel_change_tol: 1.0e-3 # NEW
```
Full file at
benchmarks/configs/fluor_3d_beads_fista.yml.Motivation
Standard TLS / Tikhonov fluorescence reconstructions produce non-physical negative voxels (~50% in dynacell mantis A549 SEC61 ER and hummingbird A549 G3BP1 stress granule data) regardless of regularization choice. FISTA removes the negatives by construction at the cost of ~30-100x more wall time (still well under a minute per 100-iter, 512^2 lateral FOV on CPU).
Scope
NotImplementedErrorfor FISTA for now.FISTAoption lives on a newApplyInverseSettingssubclass inwaveorder/api/fluorescence.pyrather than the sharedFourierApplyInverseSettings, so phase / birefringence schemas stay clean.Changes
waveorder/api/fluorescence.py: newApplyInverseSettings(FourierApplyInverseSettings)widens the algorithm Literal and addsFISTA_max_iter/FISTA_rel_change_tol. Apply-inverse dispatcher filters FISTA-only kwargs before calling the 2D entry-point and rejects 2D FISTA with a clear message.waveorder/models/isotropic_fluorescent_thick_3d.py: FISTA branch with constant step size1 / L,L = max(|OTF|^2) + lambda. Two FFTs per iteration (FFT(z), IFFT(residual_fft * conj(OTF))), early stop on||x_{k+1} - x_k|| / ||x_k|| < FISTA_rel_change_tol.benchmarks/configs/fluor_3d_beads_fista.yml: example config.Tested
Smoke test on
simulate(...)phantom in 3D: Tikhonov and FISTA both reconstruct the bead within a few counts of the true intensity; FISTA stays strictly non-negative. 2D FISTA correctly raises NotImplementedError.```
phantom range: 0.0 1.0
data range: 10.07 10.55
Tikhonov out: min=9.57 max=10.90 frac<0=0.000
FISTA out: min=9.49 max=10.80 frac<0=0.000
OK: FISTA in 2D raised: FISTA reconstruction is currently only implemented for 3D fluorescence
```
Follow-ups (not in this PR)
isotropic_fluorescent_thin_3d.apply_inverse_transfer_function(different forward model — singular-system convolution).Test plan