Skip to content

Commit c28850b

Browse files
authored
Merge pull request #1154 from MouseLand/pytest_slow
add --runslow option to pytest
2 parents e5b26b9 + b3ab7ef commit c28850b

File tree

4 files changed

+131
-123
lines changed

4 files changed

+131
-123
lines changed

conftest.py

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import time
2+
import numpy as np
23
import pytest
34
from cellpose import utils, models, vit_sam
45
import zipfile
@@ -7,6 +8,26 @@
78
from pathlib import Path
89

910

11+
def pytest_addoption(parser):
12+
parser.addoption(
13+
"--runslow", action="store_true", default=False, help="run slow tests"
14+
)
15+
16+
17+
def pytest_configure(config):
18+
config.addinivalue_line("markers", "slow: mark test as slow to run")
19+
20+
21+
def pytest_collection_modifyitems(config, items):
22+
if config.getoption("--runslow"):
23+
# --runslow given in cli: do not skip slow tests
24+
return
25+
skip_slow = pytest.mark.skip(reason="need --runslow option to run")
26+
for item in items:
27+
if "slow" in item.keywords:
28+
item.add_marker(skip_slow)
29+
30+
1031
@pytest.fixture()
1132
def image_names():
1233
image_names = ['rgb_2D_tif.tif', 'rgb_2D.png', 'gray_2D.png']
@@ -58,7 +79,7 @@ def __init__(self, use_layers: int):
5879
super().__init__()
5980

6081
self.use_layers = use_layers
61-
82+
self.layer_idxs = np.linspace(0, 23, self.use_layers, dtype=int)
6283

6384
def forward(self, x):
6485
# same progression as SAM until readout
@@ -68,10 +89,8 @@ def forward(self, x):
6889
x = x + self.encoder.pos_embed
6990

7091
# only use self.use_layers layers
71-
for i, block in enumerate(self.encoder.blocks):
72-
if i == self.use_layers:
73-
break
74-
x = block(x)
92+
for layer_idx in self.layer_idxs:
93+
x = self.encoder.blocks[layer_idx](x)
7594

7695
x = self.encoder.neck(x.permute(0, 3, 1, 2))
7796

tests/test_import.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ def test_gui_imports_without_error():
1414

1515

1616
def test_gpu_check():
17-
# from cellpose import models
18-
# models.use_gpu()
1917
from cellpose import core
2018
core.use_gpu()
2119

tests/test_output.py

Lines changed: 59 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
from cellpose import io, metrics
2-
from cellpose.models import CellposeModel
3-
import platform
1+
from cellpose import io, metrics, utils
2+
import pytest
43
from subprocess import check_output, STDOUT
54
import os
65
import numpy as np
@@ -62,22 +61,22 @@ def test_class_2D(data_dir, image_names, cellposemodel_fixture_2D):
6261
compare_masks_cp4(data_dir, image_names[0], "2D")
6362
clear_output(data_dir, image_names)
6463

65-
# def test_cyto2_to_seg(data_dir, image_names):
66-
# clear_output(data_dir, image_names)
67-
# use_gpu = torch.cuda.is_available()
68-
# file_names = [data_dir / "2D" / n for n in image_names]
69-
# imgs = [io.imread_2D(file_name) for file_name in file_names]
70-
# model = models.CellposeModel(gpu=use_gpu)
7164

72-
# # masks, flows, styles = model.eval(imgs, diameter=30) # Errors during SAM stuff
73-
# masks, flows, _ = model.eval(imgs, bsize=256, batch_size=64, normalize=True)
65+
@pytest.mark.slow
66+
def test_cyto2_to_seg(data_dir, image_names, cellposemodel_fixture_2D):
67+
clear_output(data_dir, image_names)
68+
file_names = [data_dir / "2D" / n for n in image_names]
69+
imgs = [io.imread_2D(file_name) for file_name in file_names]
70+
71+
# masks, flows, styles = model.eval(imgs, diameter=30) # Errors during SAM stuff
72+
masks, flows, _ = cellposemodel_fixture_2D.eval(imgs, bsize=256, batch_size=64, normalize=True)
7473

75-
# for file_name, mask in zip(file_names, masks):
76-
# io.imsave(data_dir/'2D'/(file_name.stem + '_cp_masks.png'), mask)
74+
for file_name, mask in zip(file_names, masks):
75+
io.imsave(data_dir/'2D'/(file_name.stem + '_cp_masks.png'), mask)
7776

78-
# io.masks_flows_to_seg(imgs, masks, flows, file_names)
79-
# compare_masks_cp4(data_dir, image_names, "2D")
80-
# clear_output(data_dir, image_names)
77+
io.masks_flows_to_seg(imgs, masks, flows, file_names)
78+
compare_masks_cp4(data_dir, image_names, "2D")
79+
clear_output(data_dir, image_names)
8180

8281

8382
def test_class_3D(data_dir, image_names_3d, cellposemodel_fixture_3D):
@@ -113,51 +112,50 @@ def test_cli_2D(data_dir, image_names):
113112
clear_output(data_dir, image_names)
114113

115114

116-
# def test_cli_3D_diam(data_dir, image_names_3d):
117-
# clear_output(data_dir, image_names_3d)
118-
# use_gpu = torch.cuda.is_available()
119-
# gpu_string = "--use_gpu" if use_gpu else ""
120-
# cmd = f"python -m cellpose --image_path {str(data_dir / "3D" / image_names_3d[0])} --do_3D --diameter 25 --save_tif {gpu_string} --verbose"
121-
# try:
122-
# cmd_stdout = check_output(cmd, stderr=STDOUT, shell=True).decode()
123-
# print(cmd_stdout)
124-
# except Exception as e:
125-
# print(e)
126-
# raise ValueError(e)
127-
# compare_masks_cp4(data_dir, image_names_3d[0], "3D")
128-
# clear_output(data_dir, image_names_3d)
129-
130-
131-
# def test_outlines_list(data_dir, image_names):
132-
# """ test both single and multithreaded by comparing them"""
133-
# clear_output(data_dir, image_names)
134-
# model_type = "cyto"
135-
# channels = [2, 1]
136-
# image_name = "rgb_2D.png"
137-
138-
# file_name = str(data_dir.joinpath("2D").joinpath(image_name))
139-
# img = io.imread(file_name)
140-
141-
# model = models.CellposeModel(model_type=model_type)
142-
# masks, _, _ = model.eval(img, diameter=30)
143-
# outlines_single = utils.outlines_list(masks, multiprocessing=False)
144-
# outlines_multi = utils.outlines_list(masks, multiprocessing=True)
145-
146-
# assert len(outlines_single) == len(outlines_multi)
147-
148-
# # Check that the outlines are the same, but not necessarily in the same order
149-
# outlines_matched = [False] * len(outlines_single)
150-
# for i, outline_single in enumerate(outlines_single):
151-
# for j, outline_multi in enumerate(outlines_multi):
152-
# if not outlines_matched[j] and np.array_equal(outline_single,
153-
# outline_multi):
154-
# outlines_matched[j] = True
155-
# break
156-
# else:
157-
# assert False, "Outline not found in outlines_multi: {}".format(
158-
# outline_single)
159-
160-
# assert all(outlines_matched), "Not all outlines in outlines_multi were matched"
115+
@pytest.mark.slow
116+
def test_cli_3D_diam(data_dir, image_names_3d):
117+
clear_output(data_dir, image_names_3d)
118+
use_gpu = torch.cuda.is_available()
119+
gpu_string = "--use_gpu" if use_gpu else ""
120+
cmd = f"python -m cellpose --image_path {str(data_dir / '3D' / image_names_3d[0])} --do_3D --diameter 25 --save_tif {gpu_string} --verbose"
121+
try:
122+
cmd_stdout = check_output(cmd, stderr=STDOUT, shell=True).decode()
123+
print(cmd_stdout)
124+
except Exception as e:
125+
print(e)
126+
raise ValueError(e)
127+
compare_masks_cp4(data_dir, image_names_3d[0], "3D")
128+
clear_output(data_dir, image_names_3d)
129+
130+
131+
@pytest.mark.slow
132+
def test_outlines_list(data_dir, image_names, cellposemodel_fixture_2D):
133+
""" test both single and multithreaded by comparing them"""
134+
clear_output(data_dir, image_names)
135+
image_name = "rgb_2D.png"
136+
137+
file_name = str(data_dir.joinpath("2D").joinpath(image_name))
138+
img = io.imread(file_name)
139+
140+
masks, _, _ = cellposemodel_fixture_2D.eval(img, diameter=30)
141+
outlines_single = utils.outlines_list(masks, multiprocessing=False)
142+
outlines_multi = utils.outlines_list(masks, multiprocessing=True)
143+
144+
assert len(outlines_single) == len(outlines_multi)
145+
146+
# Check that the outlines are the same, but not necessarily in the same order
147+
outlines_matched = [False] * len(outlines_single)
148+
for i, outline_single in enumerate(outlines_single):
149+
for j, outline_multi in enumerate(outlines_multi):
150+
if not outlines_matched[j] and np.array_equal(outline_single,
151+
outline_multi):
152+
outlines_matched[j] = True
153+
break
154+
else:
155+
assert False, "Outline not found in outlines_multi: {}".format(
156+
outline_single)
157+
158+
assert all(outlines_matched), "Not all outlines in outlines_multi were matched"
161159

162160

163161
def compare_masks_cp4(data_dir, image_names, runtype):

tests/test_shape.py

Lines changed: 48 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
1-
import platform
2-
from cellpose.models import CellposeModel
31
import numpy as np
2+
import pytest
43

54

65
#################### 2D Tests ####################
7-
# def test_shape_2D_grayscale():
8-
# img = np.zeros((224, 224))
9-
# model = models.CellposeModel()
10-
# masks, _, _ = model.eval(img)
11-
# assert masks.shape == (224, 224)
6+
@pytest.mark.slow
7+
def test_shape_2D_grayscale(cellposemodel_fixture_2D):
8+
img = np.zeros((224, 224))
9+
masks, _, _ = cellposemodel_fixture_2D.eval(img)
10+
assert masks.shape == (224, 224)
1211

1312

1413
def test_shape_2D_chan_first_diam_resize(cellposemodel_fixture_2D):
@@ -19,11 +18,11 @@ def test_shape_2D_chan_first_diam_resize(cellposemodel_fixture_2D):
1918
assert flows[2].shape == (224, 224), 'cellprob shape mismatch'
2019

2120

22-
# def test_shape_2D_chan_diam_resize():
23-
# img = np.zeros((1, 224, 224))
24-
# model = models.CellposeModel()
25-
# masks, _, _ = model.eval(img, diameter=50)
26-
# assert masks.shape == (224, 224)
21+
@pytest.mark.slow
22+
def test_shape_2D_chan_diam_resize(cellposemodel_fixture_2D):
23+
img = np.zeros((1, 224, 224))
24+
masks, _, _ = cellposemodel_fixture_2D.eval(img, diameter=50)
25+
assert masks.shape == (224, 224)
2726

2827

2928
def test_shape_2D_chan_last(cellposemodel_fixture_2D):
@@ -35,11 +34,11 @@ def test_shape_2D_chan_last(cellposemodel_fixture_2D):
3534

3635

3736

38-
# def test_shape_2D_chan_specify():
39-
# img = np.zeros((224, 224, 2))
40-
# model = models.CellposeModel()
41-
# masks, _, _ = model.eval(img, channel_axis=-1)
42-
# assert masks.shape == (224, 224)
37+
@pytest.mark.slow
38+
def test_shape_2D_chan_specify(cellposemodel_fixture_2D):
39+
img = np.zeros((224, 224, 2))
40+
masks, _, _ = cellposemodel_fixture_2D.eval(img, channel_axis=-1)
41+
assert masks.shape == (224, 224)
4342

4443

4544
def test_shape_2D_2chan_specify(cellposemodel_fixture_2D):
@@ -63,36 +62,32 @@ def test_shape_stitch(cellposemodel_fixture_3D):
6362
assert flows[2].shape == (5, 80, 80), 'cellprob shape mismatch'
6463

6564

66-
# def test_shape_3D():
67-
# img = np.zeros((80, 80, 5, 1))
68-
# use_gpu = torch.cuda.is_available()
69-
# model = models.CellposeModel(gpu=use_gpu)
70-
# masks, _, _ = model.eval(img, channel_axis=3, z_axis=2, do_3D=True)
71-
# assert masks.shape == (5, 80, 80)
65+
@pytest.mark.slow
66+
def test_shape_3D(cellposemodel_fixture_3D):
67+
img = np.zeros((80, 80, 5, 1))
68+
masks, _, _ = cellposemodel_fixture_3D.eval(img, channel_axis=3, z_axis=2, do_3D=True)
69+
assert masks.shape == (5, 80, 80)
7270

7371

74-
# def test_shape_3D_1ch():
75-
# img = np.zeros((5, 80, 80, 1))
76-
# use_gpu = torch.cuda.is_available()
77-
# model = models.CellposeModel(gpu=use_gpu)
78-
# masks, _, _ = model.eval(img, channel_axis=3, z_axis=0, do_3D=True)
79-
# assert masks.shape == (5, 80, 80)
72+
@pytest.mark.slow
73+
def test_shape_3D_1ch(cellposemodel_fixture_3D):
74+
img = np.zeros((5, 80, 80, 1))
75+
masks, _, _ = cellposemodel_fixture_3D.eval(img, channel_axis=3, z_axis=0, do_3D=True)
76+
assert masks.shape == (5, 80, 80)
8077

8178

82-
# def test_shape_3D_1ch_3ndim():
83-
# img = np.zeros((5, 80, 80))
84-
# use_gpu = torch.cuda.is_available()
85-
# model = models.CellposeModel(gpu=use_gpu)
86-
# masks, _, _ = model.eval(img, channel_axis=None, z_axis=0, do_3D=True)
87-
# assert masks.shape == (5, 80, 80)
79+
@pytest.mark.slow
80+
def test_shape_3D_1ch_3ndim(cellposemodel_fixture_3D):
81+
img = np.zeros((5, 80, 80))
82+
masks, _, _ = cellposemodel_fixture_3D.eval(img, channel_axis=None, z_axis=0, do_3D=True)
83+
assert masks.shape == (5, 80, 80)
8884

8985

90-
# def test_shape_3D_1ch_3ndim_diam():
91-
# img = np.zeros((5, 80, 80))
92-
# use_gpu = torch.cuda.is_available()
93-
# model = models.CellposeModel(gpu=use_gpu)
94-
# masks, _, _ = model.eval(img, channel_axis=None, diameter=50, z_axis=0, do_3D=True)
95-
# assert masks.shape == (5, 80, 80)
86+
@pytest.mark.slow
87+
def test_shape_3D_1ch_3ndim_diam(cellposemodel_fixture_3D):
88+
img = np.zeros((5, 80, 80))
89+
masks, _, _ = cellposemodel_fixture_3D.eval(img, channel_axis=None, diameter=50, z_axis=0, do_3D=True)
90+
assert masks.shape == (5, 80, 80)
9691

9792

9893
def test_shape_3D_2ch(cellposemodel_fixture_3D):
@@ -104,18 +99,16 @@ def test_shape_3D_2ch(cellposemodel_fixture_3D):
10499
assert flows[2].shape == (4, 80, 80), 'cellprob shape mismatch'
105100

106101

107-
# def test_shape_3D_rgb_diam():
108-
# img = np.zeros((5, 80, 80, 3))
109-
# use_gpu = torch.cuda.is_available()
110-
# model = models.CellposeModel(gpu=use_gpu)
111-
# masks, _, _ = model.eval(img, diameter=50, channels=[0, 0],
112-
# channel_axis=3, z_axis=0, do_3D=True)
113-
# assert masks.shape == (5, 80, 80)
102+
@pytest.mark.slow
103+
def test_shape_3D_rgb_diam(cellposemodel_fixture_3D):
104+
img = np.zeros((5, 80, 80, 3))
105+
masks, _, _ = cellposemodel_fixture_3D.eval(img, diameter=50, channels=[0, 0],
106+
channel_axis=3, z_axis=0, do_3D=True)
107+
assert masks.shape == (5, 80, 80)
114108

115-
# def test_shape_3D_rgb():
116-
# img = np.zeros((5, 80, 80, 3))
117-
# use_gpu = torch.cuda.is_available()
118-
# model = models.CellposeModel(gpu=use_gpu)
119-
# masks, _, _ = model.eval(img, channels=[0, 0],
120-
# channel_axis=3, z_axis=0, do_3D=True)
121-
# assert masks.shape == (5, 80, 80)
109+
@pytest.mark.slow
110+
def test_shape_3D_rgb(cellposemodel_fixture_3D):
111+
img = np.zeros((5, 80, 80, 3))
112+
masks, _, _ = cellposemodel_fixture_3D.eval(img, channels=[0, 0],
113+
channel_axis=3, z_axis=0, do_3D=True)
114+
assert masks.shape == (5, 80, 80)

0 commit comments

Comments
 (0)