dcnum 0.11.4__py3-none-any.whl → 0.11.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of dcnum might be problematic. Click here for more details.
- dcnum/_version.py +2 -2
- dcnum/feat/queue_event_extractor.py +15 -1
- dcnum/write/queue_collector_thread.py +8 -3
- {dcnum-0.11.4.dist-info → dcnum-0.11.6.dist-info}/METADATA +1 -1
- {dcnum-0.11.4.dist-info → dcnum-0.11.6.dist-info}/RECORD +8 -30
- dcnum-0.11.6.dist-info/top_level.txt +1 -0
- dcnum-0.11.4.dist-info/top_level.txt +0 -4
- docs/conf.py +0 -87
- docs/extensions/github_changelog.py +0 -75
- docs/index.rst +0 -20
- docs/requirements.txt +0 -7
- tests/conftest.py +0 -20
- tests/data/fmt-hdf5_cytoshot_full-features_2023.zip +0 -0
- tests/data/fmt-hdf5_cytoshot_full-features_legacy_allev_2023.zip +0 -0
- tests/helper_methods.py +0 -72
- tests/requirements.txt +0 -2
- tests/test_feat_background_bg_roll_median.py +0 -131
- tests/test_feat_brightness.py +0 -56
- tests/test_feat_haralick.py +0 -120
- tests/test_feat_moments_based.py +0 -108
- tests/test_init.py +0 -5
- tests/test_ppid.py +0 -94
- tests/test_ppid_segm.py +0 -8
- tests/test_read_concat_hdf5.py +0 -54
- tests/test_read_hdf5.py +0 -196
- tests/test_segm_thresh.py +0 -139
- tests/test_segmenter.py +0 -225
- tests/test_write_deque_writer_thread.py +0 -42
- tests/test_write_writer.py +0 -33
- {dcnum-0.11.4.dist-info → dcnum-0.11.6.dist-info}/LICENSE +0 -0
- {dcnum-0.11.4.dist-info → dcnum-0.11.6.dist-info}/WHEEL +0 -0
tests/test_feat_haralick.py
DELETED
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
import pathlib
|
|
2
|
-
|
|
3
|
-
import h5py
|
|
4
|
-
import numpy as np
|
|
5
|
-
|
|
6
|
-
from dcnum.feat import feat_texture
|
|
7
|
-
|
|
8
|
-
from helper_methods import retrieve_data
|
|
9
|
-
|
|
10
|
-
data_path = pathlib.Path(__file__).parent / "data"
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def test_basic_haralick():
|
|
14
|
-
# This original file was generated with dcevent for reference.
|
|
15
|
-
path = retrieve_data(data_path /
|
|
16
|
-
"fmt-hdf5_cytoshot_full-features_2023.zip")
|
|
17
|
-
# Make data available
|
|
18
|
-
with h5py.File(path) as h5:
|
|
19
|
-
ret_arr = feat_texture.haralick_texture_features(
|
|
20
|
-
image=h5["events/image"][:],
|
|
21
|
-
image_bg=h5["events/image_bg"][:],
|
|
22
|
-
mask=h5["events/mask"][:],
|
|
23
|
-
)
|
|
24
|
-
|
|
25
|
-
assert np.allclose(ret_arr["tex_asm_avg"][1],
|
|
26
|
-
0.001514295993357114,
|
|
27
|
-
atol=0, rtol=1e-10)
|
|
28
|
-
for feat in feat_texture.haralick_names:
|
|
29
|
-
assert np.allclose(h5["events"][feat],
|
|
30
|
-
ret_arr[feat])
|
|
31
|
-
# control test
|
|
32
|
-
assert not np.allclose(h5["events"]["tex_asm_avg"],
|
|
33
|
-
ret_arr["tex_asm_ptp"])
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
def test_empty_image():
|
|
37
|
-
masks = np.array([
|
|
38
|
-
[0, 0, 0, 0, 0, 0],
|
|
39
|
-
[0, 0, 0, 0, 0, 0],
|
|
40
|
-
[0, 0, 1, 1, 0, 0],
|
|
41
|
-
[0, 0, 1, 1, 0, 0],
|
|
42
|
-
[0, 0, 0, 0, 0, 0],
|
|
43
|
-
[0, 0, 0, 0, 0, 0],
|
|
44
|
-
], dtype=bool)[np.newaxis]
|
|
45
|
-
image_corr = np.zeros(6*6, dtype=np.int16).reshape(1, 6, 6)
|
|
46
|
-
tex = feat_texture.haralick_texture_features(
|
|
47
|
-
image_corr=image_corr,
|
|
48
|
-
mask=masks,
|
|
49
|
-
)
|
|
50
|
-
assert np.allclose(tex["tex_con_avg"][0], 0)
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
def test_empty_mask():
|
|
54
|
-
masks = np.array([
|
|
55
|
-
[0, 0, 0, 0, 0, 0],
|
|
56
|
-
[0, 0, 0, 0, 0, 0],
|
|
57
|
-
[0, 0, 0, 0, 0, 0],
|
|
58
|
-
[0, 0, 0, 0, 0, 0],
|
|
59
|
-
[0, 0, 0, 0, 0, 0],
|
|
60
|
-
[0, 0, 0, 0, 0, 0],
|
|
61
|
-
], dtype=bool)[np.newaxis]
|
|
62
|
-
image_corr = np.arange(6*6, dtype=np.int16).reshape(1, 6, 6)
|
|
63
|
-
tex = feat_texture.haralick_texture_features(
|
|
64
|
-
image_corr=image_corr,
|
|
65
|
-
mask=masks,
|
|
66
|
-
)
|
|
67
|
-
assert np.isnan(tex["tex_con_avg"][0])
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
def test_1d_mask_image():
|
|
71
|
-
masks = np.array([
|
|
72
|
-
[0, 0, 0, 0, 0, 0],
|
|
73
|
-
[0, 0, 0, 0, 0, 0],
|
|
74
|
-
[0, 0, 1, 0, 0, 0],
|
|
75
|
-
[0, 0, 1, 0, 0, 0],
|
|
76
|
-
[0, 0, 0, 0, 0, 0],
|
|
77
|
-
[0, 0, 0, 0, 0, 0],
|
|
78
|
-
], dtype=bool)[np.newaxis]
|
|
79
|
-
image_corr = np.arange(6*6, dtype=np.int16).reshape(1, 6, 6)
|
|
80
|
-
tex = feat_texture.haralick_texture_features(
|
|
81
|
-
image_corr=image_corr,
|
|
82
|
-
mask=masks,
|
|
83
|
-
)
|
|
84
|
-
assert np.isnan(tex["tex_con_avg"][0])
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
def test_nd_mask_with_1d_image():
|
|
88
|
-
mask = np.array([
|
|
89
|
-
[0, 0, 0, 0, 0, 0],
|
|
90
|
-
[0, 0, 0, 0, 0, 0],
|
|
91
|
-
[0, 0, 1, 1, 0, 0],
|
|
92
|
-
[0, 0, 1, 1, 0, 0],
|
|
93
|
-
[0, 0, 0, 0, 0, 0],
|
|
94
|
-
[0, 0, 0, 0, 0, 0],
|
|
95
|
-
], dtype=bool)
|
|
96
|
-
masks = np.stack([mask, mask, mask, mask])
|
|
97
|
-
image_corr = np.arange(6*6, dtype=np.int16).reshape(1, 6, 6)
|
|
98
|
-
tex = feat_texture.haralick_texture_features(
|
|
99
|
-
image_corr=image_corr,
|
|
100
|
-
mask=masks,
|
|
101
|
-
)
|
|
102
|
-
assert len(tex["tex_con_avg"]) == 4
|
|
103
|
-
assert np.allclose(tex["tex_con_avg"][0], 27.75)
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
def test_simple_mask_image():
|
|
107
|
-
masks = np.array([
|
|
108
|
-
[0, 0, 0, 0, 0, 0],
|
|
109
|
-
[0, 0, 0, 0, 0, 0],
|
|
110
|
-
[0, 0, 1, 1, 0, 0],
|
|
111
|
-
[0, 0, 1, 1, 0, 0],
|
|
112
|
-
[0, 0, 0, 0, 0, 0],
|
|
113
|
-
[0, 0, 0, 0, 0, 0],
|
|
114
|
-
], dtype=bool)[np.newaxis]
|
|
115
|
-
image_corr = np.arange(6*6, dtype=np.int16).reshape(1, 6, 6)
|
|
116
|
-
tex = feat_texture.haralick_texture_features(
|
|
117
|
-
image_corr=image_corr,
|
|
118
|
-
mask=masks,
|
|
119
|
-
)
|
|
120
|
-
assert np.allclose(tex["tex_con_avg"][0], 27.75)
|
tests/test_feat_moments_based.py
DELETED
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import pathlib
|
|
2
|
-
|
|
3
|
-
import h5py
|
|
4
|
-
import numpy as np
|
|
5
|
-
|
|
6
|
-
from dcnum.feat import feat_moments
|
|
7
|
-
|
|
8
|
-
from helper_methods import retrieve_data
|
|
9
|
-
|
|
10
|
-
data_path = pathlib.Path(__file__).parent / "data"
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
def test_moments_based_features():
|
|
14
|
-
# This original file was generated with dcevent for reference.
|
|
15
|
-
path = retrieve_data(data_path /
|
|
16
|
-
"fmt-hdf5_cytoshot_full-features_2023.zip")
|
|
17
|
-
feats = [
|
|
18
|
-
"deform",
|
|
19
|
-
"size_x",
|
|
20
|
-
"size_y",
|
|
21
|
-
"pos_x",
|
|
22
|
-
"pos_y",
|
|
23
|
-
"area_msd",
|
|
24
|
-
"area_ratio",
|
|
25
|
-
"area_um",
|
|
26
|
-
"aspect",
|
|
27
|
-
"tilt",
|
|
28
|
-
"inert_ratio_cvx",
|
|
29
|
-
"inert_ratio_raw",
|
|
30
|
-
"inert_ratio_prnc",
|
|
31
|
-
]
|
|
32
|
-
|
|
33
|
-
# Make data available
|
|
34
|
-
with h5py.File(path) as h5:
|
|
35
|
-
data = feat_moments.moments_based_features(
|
|
36
|
-
mask=h5["events/mask"][:],
|
|
37
|
-
pixel_size=0.2645
|
|
38
|
-
)
|
|
39
|
-
for feat in feats:
|
|
40
|
-
if feat.count("inert"):
|
|
41
|
-
rtol = 2e-5
|
|
42
|
-
atol = 1e-8
|
|
43
|
-
else:
|
|
44
|
-
rtol = 1e-5
|
|
45
|
-
atol = 1e-8
|
|
46
|
-
assert np.allclose(h5["events"][feat][:],
|
|
47
|
-
data[feat],
|
|
48
|
-
rtol=rtol,
|
|
49
|
-
atol=atol), f"Feature {feat} mismatch!"
|
|
50
|
-
# control test
|
|
51
|
-
assert not np.allclose(h5["events"]["inert_ratio_cvx"][:],
|
|
52
|
-
data["tilt"])
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
def test_mask_0d():
|
|
56
|
-
masks = np.array([
|
|
57
|
-
[0, 0, 0, 0, 0, 0],
|
|
58
|
-
[0, 0, 0, 0, 0, 0],
|
|
59
|
-
[0, 0, 1, 0, 0, 0],
|
|
60
|
-
[0, 0, 0, 0, 0, 0],
|
|
61
|
-
[0, 0, 0, 0, 0, 0],
|
|
62
|
-
[0, 0, 0, 0, 0, 0],
|
|
63
|
-
], dtype=bool)[np.newaxis]
|
|
64
|
-
data = feat_moments.moments_based_features(
|
|
65
|
-
mask=masks,
|
|
66
|
-
pixel_size=0.2645
|
|
67
|
-
)
|
|
68
|
-
assert data["deform"].shape == (1,)
|
|
69
|
-
assert np.isnan(data["deform"][0])
|
|
70
|
-
assert np.isnan(data["area_um"][0])
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
def test_mask_1d():
|
|
74
|
-
masks = np.array([
|
|
75
|
-
[0, 0, 0, 0, 0, 0],
|
|
76
|
-
[0, 0, 0, 0, 0, 0],
|
|
77
|
-
[0, 0, 1, 0, 0, 0],
|
|
78
|
-
[0, 0, 1, 0, 0, 0],
|
|
79
|
-
[0, 0, 0, 0, 0, 0],
|
|
80
|
-
[0, 0, 0, 0, 0, 0],
|
|
81
|
-
], dtype=bool)[np.newaxis]
|
|
82
|
-
data = feat_moments.moments_based_features(
|
|
83
|
-
mask=masks,
|
|
84
|
-
pixel_size=0.2645
|
|
85
|
-
)
|
|
86
|
-
assert data["deform"].shape == (1,)
|
|
87
|
-
assert np.isnan(data["deform"][0])
|
|
88
|
-
assert np.isnan(data["area_um"][0])
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
def test_mask_2d():
|
|
92
|
-
masks = np.array([
|
|
93
|
-
[0, 0, 0, 0, 0, 0],
|
|
94
|
-
[0, 0, 0, 0, 0, 0],
|
|
95
|
-
[0, 0, 1, 1, 0, 0],
|
|
96
|
-
[0, 0, 1, 1, 0, 0],
|
|
97
|
-
[0, 0, 0, 0, 0, 0],
|
|
98
|
-
[0, 0, 0, 0, 0, 0],
|
|
99
|
-
], dtype=bool)[np.newaxis]
|
|
100
|
-
data = feat_moments.moments_based_features(
|
|
101
|
-
mask=masks,
|
|
102
|
-
pixel_size=0.2645
|
|
103
|
-
)
|
|
104
|
-
assert data["deform"].shape == (1,)
|
|
105
|
-
# This is the deformation of a square (compared to circle)
|
|
106
|
-
assert np.allclose(data["deform"][0], 0.11377307454724206)
|
|
107
|
-
# Without moments-based computation, this would be 4*pxsize=0.066125
|
|
108
|
-
assert np.allclose(data["area_um"][0], 0.06996025)
|
tests/test_init.py
DELETED
tests/test_ppid.py
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import inspect
|
|
2
|
-
|
|
3
|
-
import pytest
|
|
4
|
-
|
|
5
|
-
from dcnum.meta import ppid
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class ExampleClass:
|
|
9
|
-
def cook(self, *,
|
|
10
|
-
temperature: float = 90.0,
|
|
11
|
-
te: str = "a",
|
|
12
|
-
outside: bool = False,
|
|
13
|
-
with_water: bool = True,
|
|
14
|
-
amount: int = 1000,
|
|
15
|
-
wine_type: str = "red",
|
|
16
|
-
test_oven: bool = True):
|
|
17
|
-
return id(self)
|
|
18
|
-
|
|
19
|
-
@classmethod
|
|
20
|
-
def key(cls):
|
|
21
|
-
return cls.__name__
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
@pytest.mark.parametrize("in_list,out_list", [
|
|
25
|
-
(["camera", "campus"],
|
|
26
|
-
["came", "camp"]),
|
|
27
|
-
(["cole", "coleman"],
|
|
28
|
-
["cole", "colem"]),
|
|
29
|
-
(["cole", "coleman", "colemine"],
|
|
30
|
-
["cole", "colema", "colemi"]),
|
|
31
|
-
(["cole", "coleman", "cundis"],
|
|
32
|
-
["cole", "colem", "cu"]),
|
|
33
|
-
(["an", "and", "anderson", "andersrum", "ant"],
|
|
34
|
-
["an", "and", "anderso", "andersr", "ant"]),
|
|
35
|
-
])
|
|
36
|
-
def test_unique_prefix_ordered(in_list, out_list):
|
|
37
|
-
t_list = ppid.get_unique_prefix(in_list)
|
|
38
|
-
assert t_list == out_list
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
@pytest.mark.parametrize("in_list,out_list", [
|
|
42
|
-
(["campus", "camera"],
|
|
43
|
-
["camp", "came"]),
|
|
44
|
-
(["coleman", "cole"],
|
|
45
|
-
["colem", "cole"]),
|
|
46
|
-
(["coleman", "cole", "colemine"],
|
|
47
|
-
["colema", "cole", "colemi"]),
|
|
48
|
-
(["cole", "cundis", "coleman"],
|
|
49
|
-
["cole", "cu", "colem"]),
|
|
50
|
-
(["an", "andersrum", "and", "anderson", "ant"],
|
|
51
|
-
["an", "andersr", "and", "anderso", "ant"]),
|
|
52
|
-
])
|
|
53
|
-
def test_unique_prefix_unordered(in_list, out_list):
|
|
54
|
-
t_list = ppid.get_unique_prefix(in_list)
|
|
55
|
-
assert t_list == out_list
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
@pytest.mark.parametrize("kwargs, pid", [
|
|
59
|
-
({},
|
|
60
|
-
"tem=90^te=a^o=0^wit=1^a=1000^win=red^tes=1"),
|
|
61
|
-
({"temperature": 10.1},
|
|
62
|
-
"tem=10.1^te=a^o=0^wit=1^a=1000^win=red^tes=1"),
|
|
63
|
-
({"with_water": False, "wine_type": "blue"},
|
|
64
|
-
"tem=90^te=a^o=0^wit=0^a=1000^win=blue^tes=1"),
|
|
65
|
-
])
|
|
66
|
-
def test_kwargs_to_ppid(kwargs, pid):
|
|
67
|
-
ptest = ppid.kwargs_to_ppid(ExampleClass, "cook", kwargs)
|
|
68
|
-
assert pid == ptest
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
@pytest.mark.parametrize("kwargs, pid", [
|
|
72
|
-
({},
|
|
73
|
-
"tem=90^te=a^o=0^wit=1^a=1000^win=red^tes=1"),
|
|
74
|
-
({"temperature": 10.1},
|
|
75
|
-
"tem=10.1^te=a^o=0^wit=1^a=1000^win=red^tes=1"),
|
|
76
|
-
({"with_water": False, "wine_type": "blue"},
|
|
77
|
-
"tem=90^te=a^o=0^wit=0^a=1000^win=blue^tes=1"),
|
|
78
|
-
({},
|
|
79
|
-
"te=a^tem=90^o=0^wit=1^a=1000^win=red^tes=1"), # switch order (evil!)
|
|
80
|
-
({},
|
|
81
|
-
"tem=90^te=a^o=0^wit=1^a=1000^win=red"), # remove things
|
|
82
|
-
({},
|
|
83
|
-
"tem=90^te=a^o=0^w=1^a=1000"), # remove more things!
|
|
84
|
-
])
|
|
85
|
-
def test_ppid_to_kwargs(kwargs, pid):
|
|
86
|
-
# get the default keyword arguments
|
|
87
|
-
meth = getattr(ExampleClass, "cook")
|
|
88
|
-
spec = inspect.getfullargspec(meth)
|
|
89
|
-
kwargs_full = spec.kwonlydefaults
|
|
90
|
-
# update with given kwargs
|
|
91
|
-
kwargs_full.update(kwargs)
|
|
92
|
-
|
|
93
|
-
kwargs_test = ppid.ppid_to_kwargs(ExampleClass, "cook", pid)
|
|
94
|
-
assert kwargs_test == kwargs_full
|
tests/test_ppid_segm.py
DELETED
tests/test_read_concat_hdf5.py
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import pathlib
|
|
2
|
-
|
|
3
|
-
from dcnum import read
|
|
4
|
-
import h5py
|
|
5
|
-
import numpy as np
|
|
6
|
-
import pytest
|
|
7
|
-
|
|
8
|
-
from helper_methods import retrieve_data
|
|
9
|
-
|
|
10
|
-
data_path = pathlib.Path(__file__).parent / "data"
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
@pytest.mark.parametrize("path_out", [None, True])
|
|
14
|
-
def test_concat_basic(path_out):
|
|
15
|
-
path = retrieve_data(data_path /
|
|
16
|
-
"fmt-hdf5_cytoshot_full-features_2023.zip")
|
|
17
|
-
# create simple concatenated dataset, repeating a file
|
|
18
|
-
data = read.concatenated_hdf5_data([path, path, path],
|
|
19
|
-
path_out=path_out)
|
|
20
|
-
assert len(data) == 120
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
@pytest.mark.parametrize("path_out", [None, True])
|
|
24
|
-
def test_concat_basic_frame(path_out):
|
|
25
|
-
path = retrieve_data(data_path /
|
|
26
|
-
"fmt-hdf5_cytoshot_full-features_2023.zip")
|
|
27
|
-
# create simple concatenated dataset, repeating a file
|
|
28
|
-
data = read.concatenated_hdf5_data([path, path, path],
|
|
29
|
-
path_out=path_out)
|
|
30
|
-
with h5py.File(path) as h5:
|
|
31
|
-
frame = h5["events/frame"][:]
|
|
32
|
-
assert frame[0] == 101
|
|
33
|
-
|
|
34
|
-
assert np.allclose(data["frame"][:frame.size],
|
|
35
|
-
frame - 101 + 1)
|
|
36
|
-
offset1 = frame[-1] - 101 + 1
|
|
37
|
-
assert np.allclose(offset1, data["frame"][frame.size-1])
|
|
38
|
-
assert np.allclose(offset1 + 1, data["frame"][frame.size])
|
|
39
|
-
assert np.allclose(data["frame"][frame.size:2*frame.size],
|
|
40
|
-
frame - 101 + offset1 + 1)
|
|
41
|
-
diff = frame[-1] - frame[0]
|
|
42
|
-
assert np.allclose(data["frame"][-1], 3 * (diff + 1))
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
def test_concat_basic_to_file(tmp_path):
|
|
46
|
-
path = retrieve_data(data_path /
|
|
47
|
-
"fmt-hdf5_cytoshot_full-features_2023.zip")
|
|
48
|
-
# create simple concatenated dataset, repeating a file
|
|
49
|
-
path_out = tmp_path / "test.rtdc"
|
|
50
|
-
assert not path_out.exists()
|
|
51
|
-
data = read.concatenated_hdf5_data([path, path, path],
|
|
52
|
-
path_out=path_out)
|
|
53
|
-
assert len(data) == 120
|
|
54
|
-
assert path_out.exists()
|
tests/test_read_hdf5.py
DELETED
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
import pathlib
|
|
2
|
-
import pickle
|
|
3
|
-
|
|
4
|
-
import h5py
|
|
5
|
-
import numpy as np
|
|
6
|
-
import pytest
|
|
7
|
-
|
|
8
|
-
from dcnum import read
|
|
9
|
-
|
|
10
|
-
from helper_methods import retrieve_data
|
|
11
|
-
|
|
12
|
-
data_path = pathlib.Path(__file__).parent / "data"
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
def test_image_cache(tmp_path):
|
|
16
|
-
path = tmp_path / "test.hdf5"
|
|
17
|
-
with h5py.File(path, "w") as hw:
|
|
18
|
-
hw["events/image"] = np.random.rand(210, 80, 180)
|
|
19
|
-
|
|
20
|
-
with h5py.File(path, "r") as h5:
|
|
21
|
-
hic = read.HDF5ImageCache(h5["events/image"],
|
|
22
|
-
chunk_size=100,
|
|
23
|
-
cache_size=2)
|
|
24
|
-
|
|
25
|
-
# Get something from the first chunk
|
|
26
|
-
assert np.allclose(hic[10], h5["events/image"][10])
|
|
27
|
-
assert len(hic.cache) == 1
|
|
28
|
-
assert 0 in hic.cache
|
|
29
|
-
|
|
30
|
-
# Get something from the last chunk
|
|
31
|
-
assert np.allclose(hic[205], h5["events/image"][205])
|
|
32
|
-
assert len(hic.cache) == 2
|
|
33
|
-
assert 0 in hic.cache
|
|
34
|
-
assert 2 in hic.cache
|
|
35
|
-
assert np.allclose(hic.cache[2], h5["events/image"][200:])
|
|
36
|
-
|
|
37
|
-
# Get something from the first chunk again
|
|
38
|
-
assert np.allclose(hic[90], h5["events/image"][90])
|
|
39
|
-
assert len(hic.cache) == 2
|
|
40
|
-
assert 0 in hic.cache
|
|
41
|
-
assert 2 in hic.cache
|
|
42
|
-
|
|
43
|
-
# Get something from the middle chunk
|
|
44
|
-
assert np.allclose(hic[140], h5["events/image"][140])
|
|
45
|
-
assert len(hic.cache) == 2 # limited to two
|
|
46
|
-
assert 0 not in hic.cache # first item gets removed
|
|
47
|
-
assert 1 in hic.cache
|
|
48
|
-
assert 2 in hic.cache
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
def test_image_cache_index_out_of_range(tmp_path):
|
|
52
|
-
path = tmp_path / "test.hdf5"
|
|
53
|
-
size = 20
|
|
54
|
-
chunk_size = 8
|
|
55
|
-
with h5py.File(path, "w") as hw:
|
|
56
|
-
hw["events/image"] = np.random.rand(size, 80, 180)
|
|
57
|
-
with h5py.File(path, "r") as h5:
|
|
58
|
-
hic = read.HDF5ImageCache(h5["events/image"],
|
|
59
|
-
chunk_size=chunk_size,
|
|
60
|
-
cache_size=2)
|
|
61
|
-
# Get something from first chunk. This should just work
|
|
62
|
-
hic.__getitem__(10)
|
|
63
|
-
# Now test out-of-bounds error
|
|
64
|
-
with pytest.raises(IndexError, match="of bounds for HDF5ImageCache"):
|
|
65
|
-
hic.__getitem__(20)
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
def test_image_chache_get_chunk_size(tmp_path):
|
|
69
|
-
path = tmp_path / "test.hdf5"
|
|
70
|
-
size = 20
|
|
71
|
-
chunk_size = 8
|
|
72
|
-
with h5py.File(path, "w") as hw:
|
|
73
|
-
hw["events/image"] = np.random.rand(size, 80, 180)
|
|
74
|
-
with h5py.File(path, "r") as h5:
|
|
75
|
-
hic = read.HDF5ImageCache(h5["events/image"],
|
|
76
|
-
chunk_size=chunk_size,
|
|
77
|
-
cache_size=2)
|
|
78
|
-
# Get something from first chunk. This should just work
|
|
79
|
-
assert hic.get_chunk_size(0) == 8
|
|
80
|
-
assert hic.get_chunk_size(1) == 8
|
|
81
|
-
assert hic.get_chunk_size(2) == 4
|
|
82
|
-
with pytest.raises(IndexError, match="only has 3 chunks"):
|
|
83
|
-
hic.get_chunk_size(3)
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
@pytest.mark.parametrize("size, chunks", [(209, 21),
|
|
87
|
-
(210, 21),
|
|
88
|
-
(211, 22)])
|
|
89
|
-
def test_image_cache_iter_chunks(size, chunks, tmp_path):
|
|
90
|
-
path = tmp_path / "test.hdf5"
|
|
91
|
-
with h5py.File(path, "w") as hw:
|
|
92
|
-
hw["events/image"] = np.random.rand(size, 80, 180)
|
|
93
|
-
with h5py.File(path, "r") as h5:
|
|
94
|
-
hic = read.HDF5ImageCache(h5["events/image"],
|
|
95
|
-
chunk_size=10,
|
|
96
|
-
cache_size=2)
|
|
97
|
-
assert list(hic.iter_chunks()) == list(range(chunks))
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
def test_pixel_size_getset(tmp_path):
|
|
101
|
-
path = tmp_path / "test.hdf5"
|
|
102
|
-
with h5py.File(path, "w") as hw:
|
|
103
|
-
hw["events/image"] = np.random.rand(10, 80, 180)
|
|
104
|
-
hw.attrs["imaging:pixel size"] = 0.123
|
|
105
|
-
|
|
106
|
-
h5dat = read.HDF5Data(path)
|
|
107
|
-
assert np.allclose(h5dat.pixel_size, 0.123)
|
|
108
|
-
h5dat.pixel_size = 0.321
|
|
109
|
-
assert np.allclose(h5dat.pixel_size, 0.321)
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
def test_open_real_data():
|
|
113
|
-
path = retrieve_data(data_path /
|
|
114
|
-
"fmt-hdf5_cytoshot_full-features_2023.zip")
|
|
115
|
-
with read.HDF5Data(path) as h5dat: # context manager
|
|
116
|
-
# properties
|
|
117
|
-
assert len(h5dat) == 40
|
|
118
|
-
assert h5dat.md5_5m == "599c8c7a112632d007be60b9c37961c5"
|
|
119
|
-
|
|
120
|
-
# scalar features
|
|
121
|
-
fsc = h5dat.features_scalar_frame
|
|
122
|
-
exp = ['bg_med', 'frame', 'time']
|
|
123
|
-
assert set(fsc) == set(exp)
|
|
124
|
-
|
|
125
|
-
# feature names
|
|
126
|
-
assert len(h5dat.keys()) == 48
|
|
127
|
-
assert "deform" in h5dat.keys()
|
|
128
|
-
assert "deform" in h5dat
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
def test_pickling_state():
|
|
132
|
-
path = retrieve_data(data_path /
|
|
133
|
-
"fmt-hdf5_cytoshot_full-features_2023.zip")
|
|
134
|
-
|
|
135
|
-
h5d1 = read.HDF5Data(path)
|
|
136
|
-
h5d1.pixel_size = 0.124
|
|
137
|
-
pstate = pickle.dumps(h5d1)
|
|
138
|
-
h5d2 = pickle.loads(pstate)
|
|
139
|
-
assert h5d1.md5_5m == h5d2.md5_5m
|
|
140
|
-
assert h5d1.md5_5m == h5d2.md5_5m
|
|
141
|
-
assert h5d1.pixel_size == h5d2.pixel_size
|
|
142
|
-
assert np.allclose(h5d2.pixel_size, 0.124)
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
def test_pickling_state_logs():
|
|
146
|
-
path = retrieve_data(
|
|
147
|
-
data_path / "fmt-hdf5_cytoshot_full-features_legacy_allev_2023.zip")
|
|
148
|
-
h5d1 = read.HDF5Data(path)
|
|
149
|
-
h5d1.pixel_size = 0.124
|
|
150
|
-
pstate = pickle.dumps(h5d1)
|
|
151
|
-
h5d2 = pickle.loads(pstate)
|
|
152
|
-
assert h5d1.logs
|
|
153
|
-
for lk in h5d1.logs:
|
|
154
|
-
assert h5d1.logs[lk] == h5d2.logs[lk]
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
def test_pickling_state_tables():
|
|
158
|
-
path = retrieve_data(
|
|
159
|
-
data_path / "fmt-hdf5_cytoshot_full-features_legacy_allev_2023.zip")
|
|
160
|
-
# The original file does not contain any tables, so we write
|
|
161
|
-
# generate a table
|
|
162
|
-
columns = ["alot", "of", "tables"]
|
|
163
|
-
ds_dt = np.dtype({'names': columns,
|
|
164
|
-
'formats': [float] * len(columns)})
|
|
165
|
-
tab_data = np.zeros((11, len(columns)))
|
|
166
|
-
tab_data[:, 0] = np.arange(11)
|
|
167
|
-
tab_data[:, 1] = 1000
|
|
168
|
-
tab_data[:, 2] = np.linspace(1, np.sqrt(2), 11)
|
|
169
|
-
rec_arr = np.rec.array(tab_data, dtype=ds_dt)
|
|
170
|
-
|
|
171
|
-
# add table to source file
|
|
172
|
-
with h5py.File(path, "a") as h5:
|
|
173
|
-
h5tab = h5.require_group("tables")
|
|
174
|
-
h5tab.create_dataset(name="sample_table",
|
|
175
|
-
data=rec_arr)
|
|
176
|
-
|
|
177
|
-
h5d1 = read.HDF5Data(path)
|
|
178
|
-
h5d1.pixel_size = 0.124
|
|
179
|
-
pstate = pickle.dumps(h5d1)
|
|
180
|
-
h5d2 = pickle.loads(pstate)
|
|
181
|
-
assert h5d1.tables
|
|
182
|
-
table = h5d1.tables["sample_table"]
|
|
183
|
-
assert len(table) == 3
|
|
184
|
-
for lk in table:
|
|
185
|
-
assert np.allclose(h5d1.tables["sample_table"][lk],
|
|
186
|
-
h5d2.tables["sample_table"][lk])
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
def test_read_empty_logs():
|
|
190
|
-
path = retrieve_data(
|
|
191
|
-
data_path / "fmt-hdf5_cytoshot_full-features_legacy_allev_2023.zip")
|
|
192
|
-
with h5py.File(path, "a") as h5:
|
|
193
|
-
h5.require_group("logs").create_dataset(name="empty_log",
|
|
194
|
-
data=[])
|
|
195
|
-
h5r = read.HDF5Data(path)
|
|
196
|
-
assert "empty_log" not in h5r.logs
|