Skip to content

feat(metrics): add smooth and baseline-corrected spectral weights#34

Draft
alxndrkalinin wants to merge 6 commits intomainfrom
feat/smooth-spectral-weights
Draft

feat(metrics): add smooth and baseline-corrected spectral weights#34
alxndrkalinin wants to merge 6 commits intomainfrom
feat/smooth-spectral-weights

Conversation

@alxndrkalinin
Copy link
Owner

@alxndrkalinin alxndrkalinin commented Mar 12, 2026

  • smooth_spectral_weights: SG-smoothed Wiener weights for spectral PCC
  • estimate_noise_baseline: frequency-dependent noise floor from running low-quantile of SG-smoothed log-power spectrum
  • baseline_snr2_weights: SNR²-based weights against freq-dependent baseline
  • spectral_pcc_baseline: new spectral PCC variant using baseline approach
  • spectral_pcc: add smooth/sg_window/sg_polyorder params for optional SG-smoothed weights

Summary by Sourcery

Introduce smoothed and baseline-corrected spectral weighting options for spectral PCC metrics.

New Features:

  • Add smooth_spectral_weights to compute Savitzky–Golay–smoothed Wiener-style spectral weights.
  • Add estimate_noise_baseline to derive a frequency-dependent noise floor from the smoothed power spectrum.
  • Add baseline_snr2_weights to compute SNR²-based spectral weights using the noise baseline.
  • Add spectral_pcc_baseline metric that applies baseline-corrected SNR² weights in Fourier-domain PCC.
  • Extend spectral_pcc to optionally use SG-smoothed spectral weights via new smoothing parameters.

Enhancements:

  • Improve flexibility of spectral PCC weighting by supporting optional smoothing parameters and alternative weight computation paths.

- smooth_spectral_weights: SG-smoothed Wiener weights for spectral PCC
- estimate_noise_baseline: frequency-dependent noise floor from
  running low-quantile of SG-smoothed log-power spectrum
- baseline_snr2_weights: SNR²-based weights against freq-dependent baseline
- spectral_pcc_baseline: new spectral PCC variant using baseline approach
- spectral_pcc: add smooth/sg_window/sg_polyorder params for optional
  SG-smoothed weights

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Mar 12, 2026

Reviewer's Guide

Adds Savitzky–Golay-smoothed spectral weights and a new baseline-corrected spectral PCC metric, plus an option for spectral_pcc to use the smoothed weights instead of the existing ones.

File-Level Changes

Change Details Files
Introduce SG-smoothed Wiener-style spectral weights and optional use in spectral_pcc.
  • Add smooth_spectral_weights to compute Wiener weights from an SG-smoothed log-power spectrum with window-length clamping and optional high-frequency cutoff
  • Extend spectral_pcc signature with smooth, sg_window, and sg_polyorder parameters and branch between existing spectral_weights and the new smooth_spectral_weights based on the smooth flag
cubic/metrics/bandlimited.py
Add frequency-dependent noise-baseline estimation and SNR²-based baseline weights, and use them to implement a new spectral_pcc_baseline variant.
  • Implement _running_quantile_1d to compute a sliding-window quantile used for baseline estimation
  • Add estimate_noise_baseline to derive a smoothed power spectrum and monotone non-increasing noise baseline from the log-power spectrum using Savitzky–Golay smoothing and a running low quantile
  • Add baseline_snr2_weights to compute SNR²-based radial weights with low-frequency exclusion, hard cutoff, and soft quantile-based capping
  • Implement spectral_pcc_baseline, mirroring spectral_pcc’s pipeline but sourcing weights from estimate_noise_baseline and baseline_snr2_weights, supporting optional frozen radial weights, and reusing existing radial binning and apodization utilities
cubic/metrics/bandlimited.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

alxndrkalinin and others added 3 commits March 12, 2026 17:35
Implement random binomial splitting (Rieger et al., Optics Express 2024)
as an alternative to checkerboard splitting for single-image FRC/FSC.
Each pixel's photon count is split into n1 ~ Binomial(n, 0.5) and
n2 = n - n1, producing two noise-independent images with preserved
Poisson statistics and no spatial subsampling.

New `split_type="binomial"` parameter threads through calculate_frc,
frc_resolution, fsc_resolution, and calculate_sectioned_fsc. Supports
counts mode (raw camera data with gain/offset/readout noise correction)
and poisson_thinning mode (fallback for float/deconvolved images).
Multi-repeat averaging via `n_repeats` produces correlation-std and
resolution-std for uncertainty quantification.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add nbins_low parameter to zero out the lowest radial frequency bins
before computing spectrally-weighted PCC, suppressing DC/illumination/
background contributions that can dominate the correlation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add frc_weights() to derive per-frequency reliability weights from
single-image FRC, and spectral_pcc_frcw() which uses these weights
for spectral PCC computation. Export both from cubic.metrics.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds new spectral weighting options and a binomial (photon-statistics-preserving) splitting path to improve robustness/interpretability of Fourier-domain correlation metrics (Spectral PCC, FRC/FSC), including uncertainty estimation via repeated splits.

Changes:

  • Introduces SG-smoothed and baseline-corrected spectral weighting utilities, plus new spectral PCC variants (baseline-based and FRC-weight-based).
  • Extends FRC/FSC preprocessing to support split_type="binomial" with optional read-noise correction and n_repeats aggregation (std estimates).
  • Adds binomial split implementation + unit tests, and updates spectral correlation data structures/docs accordingly.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
cubic/metrics/bandlimited.py Adds smoothed/baseline/FRC-derived spectral weighting functions and extends spectral_pcc with optional smoothing + low-k exclusion.
cubic/metrics/spectral/frc.py Adds binomial split support to FRC/FSC workflows, including repeat RNG handling and optional std outputs.
cubic/image_utils.py Implements binomial_split (counts + poisson thinning modes) used by single-image FRC/FSC.
cubic/metrics/spectral/analysis.py Extends result containers to include correlation-std and resolution-std fields.
cubic/metrics/spectral/README.md Documents checkerboard vs binomial splitting and recommended usage patterns.
cubic/metrics/__init__.py Exposes new bandlimited metrics helpers (frc_weights, spectral_pcc_frcw).
tests/test_image_utils.py Adds unit tests covering statistical/behavioral properties of binomial_split.
tests/metrics/spectral/test_frc.py Adds integration tests for binomial-split FRC/FSC behavior and repeat/stability expectations.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

alxndrkalinin and others added 2 commits March 12, 2026 20:57
- Use cubic.cuda abstraction (to_same_device/asnumpy) in binomial_split (C1)
- Derive frequency scaling factor from image dimensions in frc_weights (C2)
- Use nanmean/nanstd for multi-repeat FRC averaging (S3)
- Add xy_std/z_std keys to single-pass binomial fsc_resolution (S4)
- Make internal baseline functions private (_estimate_noise_baseline, etc) (S5)
- Document resolution averaging asymmetry in FRC (S7)
- Add ndim, gain, readout_noise_rms validation to binomial_split (N1)
- Fix "1-bit" → "1/7" in frc_weights docstring (N2)
- Replace assert with raise ValueError in frc_weights (N3)
- Extract duplicate binomial log message to module constant (N4)
- Fix checkerboard uncertainty in README table (N6)
- Fix bin_delta type annotation to int in spectral_pcc_frcw (N7)
- Add __all__ to bandlimited.py (N8)
- Fix SG window fallback for tiny arrays in smooth_spectral_weights (Copilot)
- Add frozen_weights length validation in spectral PCC functions (Copilot)
- Fix gain convention docstring in binomial_split (Copilot)
- Add nbins_low to spectral_pcc docstring (Copilot)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Replace xp/get_array_module pattern with to_same_device in all three
  spectral PCC functions (CLAUDE.md: prefer cubic.cuda abstractions)
- Use cubic.scipy proxy for savgol_filter and median_filter instead of
  direct scipy imports (CLAUDE.md: device-agnostic wrappers)
- Add xy_std/z_std keys to fsc_resolution mask backend return path to
  match the documented return contract
- Warn when n_repeats>1 is silently ignored (checkerboard or two-image)
- Clarify n_repeats docstring: requires single-image + binomial mode
- Add tests for spectral_pcc(smooth=True) and nbins_low parameter

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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