Skip to content

Commit e95f936

Browse files
committed
Always initialize saturations
1 parent bb881c5 commit e95f936

3 files changed

Lines changed: 77 additions & 3 deletions

File tree

cellpose/gui/gui.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ class MainW(QMainWindow):
177177
def __init__(self, image=None, logger=None):
178178
super(MainW, self).__init__()
179179

180-
self.logger = logger
180+
self.logger = logger if logger is not None else logging.getLogger(__name__)
181181
pg.setConfigOptions(imageAxisOrder="row-major")
182182
self.setGeometry(50, 50, 1200, 1000)
183183
self.setWindowTitle(f"cellpose v{version}")
@@ -2153,4 +2153,4 @@ def go_next_previous_dropdown(self, dropdown, increment=1):
21532153
return
21542154
idx += increment
21552155

2156-
self.logger.error('Could not find an emabled dropdown item.')
2156+
self.logger.error('Could not find an emabled dropdown item.')

cellpose/gui/io.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,18 @@ def _initialize_images(parent, image, load_3D=False):
212212
if parent.restore is None or parent.restore != "filter":
213213
parent.logger.info(": normalization checked: computing saturation levels (and optionally filtered image)")
214214
parent.compute_saturation()
215-
215+
else:
216+
# auto-adjust off: re-size saturation list to match NZ while
217+
# preserving the user's per-channel values (first-Z value is
218+
# broadcast across the new Z range).
219+
prev = parent.saturation if hasattr(parent, 'saturation') else []
220+
parent.saturation = []
221+
for r in range(3):
222+
if r < len(prev) and len(prev[r]) > 0:
223+
sval = prev[r][0]
224+
else:
225+
sval = [0, 255]
226+
parent.saturation.append([list(sval) for n in range(parent.NZ)])
216227
parent.compute_scale()
217228
parent.track_changes = []
218229

tests/test_gui.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import numpy as np
2+
import pytest
3+
4+
5+
@pytest.fixture(scope="module")
6+
def qapp():
7+
from qtpy.QtWidgets import QApplication
8+
app = QApplication.instance() or QApplication([])
9+
yield app
10+
11+
12+
@pytest.fixture(scope="module")
13+
def win(qapp):
14+
from cellpose.gui.gui3d import MainW_3d
15+
return MainW_3d()
16+
17+
18+
def test_saturation_invariants_with_autobtn_unchecked(win):
19+
"""Regression: when 'auto-adjust saturation' is unchecked, loading a 3D
20+
image must (1) leave self.saturation sized 3 x NZ so that update_plot's
21+
self.saturation[c][currentZ] index is valid, and (2) preserve the user's
22+
per-channel values across reloads that change NZ."""
23+
from cellpose.gui import io as gui_io
24+
25+
win.autobtn.setChecked(False)
26+
27+
# First load: NZ=10, saturation must be 3 x 10 with valid [lo, hi] entries.
28+
win.load_3D = True
29+
win.filename = "test.tif"
30+
gui_io._initialize_images(
31+
win, np.zeros((10, 64, 64, 3), dtype=np.float32), load_3D=True
32+
)
33+
34+
assert win.NZ == 10
35+
assert len(win.saturation) == 3
36+
for c in range(3):
37+
assert len(win.saturation[c]) == win.NZ
38+
for z in range(win.NZ):
39+
assert len(win.saturation[c][z]) == 2 # [lo, hi]
40+
41+
# Trigger the original failure path explicitly: move_in_Z -> update_plot
42+
# -> setLevels(self.saturation[self.color - 1][self.currentZ]).
43+
win.loaded = True
44+
win.color = 1 # red channel (color > 0 and < 4 branch)
45+
win.nchan = 3
46+
win.scroll.setValue(win.NZ - 1)
47+
win.move_in_Z() # would have raised IndexError pre-fix
48+
49+
# User picks custom per-channel values.
50+
for c in range(3):
51+
for z in range(win.NZ):
52+
win.saturation[c][z] = [10 + c, 200 + c]
53+
54+
# Reload with a different NZ; user values should be broadcast across new Z.
55+
gui_io._initialize_images(
56+
win, np.zeros((8, 64, 64, 3), dtype=np.float32), load_3D=True
57+
)
58+
59+
assert win.NZ == 8
60+
for c in range(3):
61+
assert len(win.saturation[c]) == win.NZ
62+
for z in range(win.NZ):
63+
assert win.saturation[c][z] == [10 + c, 200 + c]

0 commit comments

Comments
 (0)