Skip to content

Add drift QC: per-FOV drift_{fov}.csv and fishtank plot-drift#14

Open
leonardosepulveda wants to merge 3 commits into
jweissmanlab:mainfrom
leonardosepulveda:add-drift-qc
Open

Add drift QC: per-FOV drift_{fov}.csv and fishtank plot-drift#14
leonardosepulveda wants to merge 3 commits into
jweissmanlab:mainfrom
leonardosepulveda:add-drift-qc

Conversation

@leonardosepulveda

@leonardosepulveda leonardosepulveda commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds drift quality-control output and a plotting command to detect-spots.

  • Per-FOV drift QC from channels_{fov}.csv. detect-spots already records the
    per-series integer-pixel drift (x_drift, y_drift) it applies during intensity
    quantification in channels_{fov}.csv. This PR reuses that record for QC rather than
    recomputing or duplicating it.
  • fishtank plot-drift. A new CLI subcommand (and fishtank.pl.plot_drift function)
    that reads the per-FOV channels_*.csv, de-duplicates to one drift value per
    (fov, series), and renders a three-panel QC figure:
    1. x vs y drift scatter, one point per (fov, round), colored by round, on square
      symmetric axes (with an outlier-resistant --scatter_max auto option);
    2. histogram of drift distance (computed from x_drift/y_drift) with the median marked;
    3. a fov x round heatmap of drift distance − median (diverging colormap).

Rationale for revisions

The original version of this PR measured drift at sub-pixel resolution
(phase_cross_correlation(..., upsample_factor=10)) and wrote a separate
drift_{fov}.csv table. Both were reverted:

  • Sub-pixel registration was dropped. upsample_factor=10 significantly slows down the
    drift calculation, and since the drift applied to images stays integer-pixel anyway, the
    extra precision was never used — it only fed the QC record. detect-spots is back to the
    original integer-pixel phase_cross_correlation(...).
  • drift_{fov}.csv was removed as redundant. The fov, series, x_drift, and
    y_drift columns it contained are already written to channels_{fov}.csv. plot-drift
    now reads channels_{fov}.csv directly (deduping to one row per (fov, series)), so there
    is a single source of truth and no extra output file.

Notes

  • Non-breaking: no new output files or columns; detect-spots behavior is unchanged.
  • Plotting uses only existing dependencies (matplotlib, numpy, pandas).
  • The figure defaults to <input>/drift_qc.png; axis limits, histogram bin width, colormap
    and font size are all parameters (with auto limits available for scatter/histogram).

🤖 Generated with Claude Code

leonardosepulveda and others added 3 commits June 23, 2026 11:52
detect-spots now measures drift at sub-pixel resolution (upsample_factor=10) and
writes a per-FOV drift table drift_{fov}.csv (fov, series, x_drift, y_drift, distance);
the applied image correction stays integer-pixel. Adds a fishtank.pl.plot_drift
function and a fishtank plot-drift CLI subcommand that render a 3-panel QC figure:
drift-vector scatter (colored by round), drift-distance histogram, and a fov x round
distance-minus-median heatmap.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reverts the upsample_factor=10 sub-pixel registration in detect-spots
(which significantly slowed drift calculation) back to integer-pixel
phase cross-correlation, and drops the redundant drift_{fov}.csv output
since x_drift/y_drift are already recorded in channels_{fov}.csv.

plot-drift now reads channels_{fov}.csv (deduped to one row per
(fov, series)) instead of drift_{fov}.csv.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The plugin argument is deprecated in skimage.io.imread, so drop the
plugin and **plugin_args parameters from read_img and the now-unused
plugin=... passthrough to imread. read_dax never accepted extra kwargs,
so **plugin_args was only ever valid when empty.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@colganwi

Copy link
Copy Markdown
Contributor

@leonardosepulveda I removed the drift_{fov}.csv file since its redundant with channels_{fov}.csv and removed the upsampling since its significantly slower. Let me know if there was a rational for upsampling beyond detecting 0 drift which should have been solved by your other PR.

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