celldetective 1.5.0b8__py3-none-any.whl → 1.5.0b9__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: celldetective
3
- Version: 1.5.0b8
3
+ Version: 1.5.0b9
4
4
  Summary: description
5
5
  Home-page: http://github.com/remyeltorro/celldetective
6
6
  Author: Rémy Torro
@@ -1,6 +1,6 @@
1
1
  celldetective/__init__.py,sha256=LfnOyfUnYPGDc8xcsF_PfYEL7-CqAb7BMBPBIWGv84o,666
2
2
  celldetective/__main__.py,sha256=Rzzu9ArxZSgfBVjV-lyn-3oanQB2MumQR6itK5ZaRpA,2597
3
- celldetective/_version.py,sha256=_aQC8i0kOHSYGEkfpTecn4OzPtL_z-LVXk1dtkjlJtQ,24
3
+ celldetective/_version.py,sha256=C-mBr40Do8xTMcYdWQX-DapmWmTsr2JSmIPIRtYIXUU,24
4
4
  celldetective/event_detection_models.py,sha256=A7ZJFhJwfdhzfxJ-YZIj6IoI9Gc1hyAodFkKt8kNxDk,93549
5
5
  celldetective/events.py,sha256=n15R53c7QZ2wT8gjb0oeNikQbuRBrVVbyNsRCqXjzXA,8166
6
6
  celldetective/exceptions.py,sha256=f3VmIYOthWTiqMEV5xQCox2rw5c5e7yog88h-CcV4oI,356
@@ -26,28 +26,28 @@ celldetective/gui/configure_new_exp.py,sha256=vgT6ozRIGDvT3R0qENlqvDn17BpKnwyJRh
26
26
  celldetective/gui/control_panel.py,sha256=dMNzgivt6GdYROPlYpEY5TTNcANenm9ifUI3W3OcpOo,24337
27
27
  celldetective/gui/dynamic_progress.py,sha256=wjTmDPy62qssY0zdteP3T9umIGGQk0UvebFIdn54CIc,16676
28
28
  celldetective/gui/event_annotator.py,sha256=JVd64Gch_qzXv29VJGAa2Ytk-WhxifZVgMK-hAxnGu4,41262
29
- celldetective/gui/generic_signal_plot.py,sha256=D3b6pG1yrSi8C2PPyYzK2yA6711CBBPRp5_OIrjayqs,49348
30
- celldetective/gui/gui_utils.py,sha256=t6SjEfjcaRH9a0TlbTGEiVRpCgocaCh4lgkIvRgRRwE,33497
29
+ celldetective/gui/generic_signal_plot.py,sha256=47kXIuMcnQXjeNEdzM_G1WbW9TL5eMSjHC9XgWXMly4,49492
30
+ celldetective/gui/gui_utils.py,sha256=l7P6emKVEciCRdmnbfYvJAhl0MnbT3QkL2zpSPuHRoY,34120
31
31
  celldetective/gui/interactions_block.py,sha256=34VaHFrdKsq1hYuXrosmpP15JU26dSfbyx4lyt1jxNg,28440
32
32
  celldetective/gui/interactive_timeseries_viewer.py,sha256=u_amAhLdEHRpYSRwPDtVm5v-JZIz0ANTcG4YGksX1Vo,16079
33
33
  celldetective/gui/json_readers.py,sha256=t5rhtIxACj0pdwLrnPs-QjyhQo3P25UGWGgOCIBhQxs,4572
34
34
  celldetective/gui/measure_annotator.py,sha256=ljNbsKmFXQk0R9zEfBZ6XfBHzFmlL7Gt6QyPHyqh08g,38357
35
35
  celldetective/gui/pair_event_annotator.py,sha256=9PT67-8FJxcL7lSDIAZcZmrW75G_R-fpRellMOsgets,128788
36
36
  celldetective/gui/plot_measurements.py,sha256=a_Mks-5XUTn2QEYih0PlXGp2lX3C34zuhK9ozzE1guM,56593
37
- celldetective/gui/plot_signals_ui.py,sha256=9VmA1yaTcNf1jY7drtK41R1q87dhEk7bXBCq_cQ94fs,28133
37
+ celldetective/gui/plot_signals_ui.py,sha256=fxgkUZ_m7jFTXOwdzfJdl8wt3n8RECny3n4Tpk-GE6w,29016
38
38
  celldetective/gui/preprocessing_block.py,sha256=cgUBv-eQBwfidK48-cTWJi0PS62wlXhsNLnsKhy6MQY,14967
39
39
  celldetective/gui/process_block.py,sha256=KVfXnC55EYGlgKVDXDSMGu_MZbxjbQaQz4Ulyl5iqSE,76881
40
40
  celldetective/gui/seg_model_loader.py,sha256=CqcyT1ZeQ27R54RmOHjAt1pfRwjtvS-Psw29PpFsT5A,23549
41
- celldetective/gui/survival_ui.py,sha256=IwdRm1gRvhkWdMtrQk04OIKKksW3NZSGYtZO_2GptrA,16034
42
- celldetective/gui/tableUI.py,sha256=kZP2lp9NwHtbWEqIyaDwohX42tRkhI0Hlf_8O5w5BD0,61267
43
- celldetective/gui/thresholds_gui.py,sha256=w6ke2TyIEi71LxbuFGz0UrwH8h21N_ESU-o6xq_NNKo,33346
41
+ celldetective/gui/survival_ui.py,sha256=YBtbkjXgJW4KLpRaFysJc_po4OjVcLyCmGSWKtMbjdk,17353
42
+ celldetective/gui/tableUI.py,sha256=8cHVKMgTHMWLf_2yxYo003FQ0TaN7Cf13rBKBZQtefQ,58989
43
+ celldetective/gui/thresholds_gui.py,sha256=KxPmCmoMGGwwHFwPWHCOr1wPTyOPR2d-zucuAvZfSqk,34783
44
44
  celldetective/gui/workers.py,sha256=WAtVxFEvHApBSAZMVyYsya_DHL_bYo8b57dbgUJQHc4,14890
45
45
  celldetective/gui/base/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
46
  celldetective/gui/base/channel_norm_generator.py,sha256=HJ57wBMdBIvca92V477T-aPuxvvC2aC5BDMssKSQKCQ,14592
47
47
  celldetective/gui/base/components.py,sha256=jNUsCU_QE7QUFR0_xEvEPFEBYolMJt7YXGUKMjF7uOE,8155
48
48
  celldetective/gui/base/feature_choice.py,sha256=n1T2fPoNLiTDS_6fa_GuGReDhBW11HdUrKy2RywotF8,2800
49
49
  celldetective/gui/base/figure_canvas.py,sha256=mSiIYvEfz7MYMgdPDf6RKSMpKN8FkeZL7lugDNnDpnM,2245
50
- celldetective/gui/base/list_widget.py,sha256=_WU3ZRU7UcJZIxm8qx_5HF7IK7dUu8IU1FY2AaW_qgo,4694
50
+ celldetective/gui/base/list_widget.py,sha256=APt7rCfMRRlFnHUwvwrwZGMTYM6M10zgu6uoHHsmmuA,4694
51
51
  celldetective/gui/base/styles.py,sha256=3Kz1eXw6OLr90wtErhK0KPJyJbyhAlqkniqm0JNGwFc,7407
52
52
  celldetective/gui/base/utils.py,sha256=KojauRKGM9XKNhaWn211p6mJNZWIHLH75yeLpDd7pvA,1103
53
53
  celldetective/gui/help/DL-segmentation-strategy.json,sha256=PZD9xXjrwbX3TiudHJPuvcyZD28o4k-fVgeTd7dBKzI,1583
@@ -92,7 +92,7 @@ celldetective/gui/viewers/base_viewer.py,sha256=Wn4na79xRL1R6PSXIoE_UabxJNtNQ-Y5
92
92
  celldetective/gui/viewers/channel_offset_viewer.py,sha256=cywBkxyMPyKIuwZTGA03DBSS4a-H1SAohMJYOPISLEE,16289
93
93
  celldetective/gui/viewers/contour_viewer.py,sha256=riHj03LKXLoa-Ys2o2EhCE5nULfcHMohx9LFoXbI6zU,14720
94
94
  celldetective/gui/viewers/size_viewer.py,sha256=uXITjaxg5dhQ09Q6TNUxwLxi-ZglyGFcxEH1RtGIZWw,6020
95
- celldetective/gui/viewers/spot_detection_viewer.py,sha256=JO7kcqATHXR91lLvo8aQ5xVYdtxkMxV-xx36s01VlNQ,12545
95
+ celldetective/gui/viewers/spot_detection_viewer.py,sha256=IsSqbdJ7Fuzc7CSIt5U8LoeHuq-GLgg-igqlw5NRn7g,16502
96
96
  celldetective/gui/viewers/threshold_viewer.py,sha256=F-13JF2wFhyvvKfUvgRcSjWL3leAliOXy5yUergndnE,12000
97
97
  celldetective/icons/logo-large.png,sha256=FXSwV3u6zEKcfpuSn4unnqB0oUnN9cHqQ9BCKWytrpg,36631
98
98
  celldetective/icons/logo.png,sha256=wV2OS8_dU5Td5cgdPbCOU3JpMpTwNuYLnfVcnQX0tJA,2437
@@ -167,7 +167,7 @@ celldetective/utils/event_detection/__init__.py,sha256=GvsdyQLMTXJj1S_FfRXjrpOxE
167
167
  celldetective/utils/plots/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
168
168
  celldetective/utils/plots/regression.py,sha256=oUCn29-hp7PxMqC-R0yoL60KMw5ZWpZAIoCDh2ErlcY,1764
169
169
  celldetective/utils/stardist_utils/__init__.py,sha256=SY2kxFNXSRjXN4ncs3heDdXT3UNk8M3dELJQySysAf4,4231
170
- celldetective-1.5.0b8.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
170
+ celldetective-1.5.0b9.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
171
171
  tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
172
172
  tests/test_cellpose_fallback.py,sha256=BJZTDFF8sFR1x7rDbvZQ2RQOB1OP6wuFBRfc8zbl5zw,3513
173
173
  tests/test_events.py,sha256=eLFwwEEJfQAdwhews3-fn1HSvzozcNNFN_Qn0gOvQkE,685
@@ -179,7 +179,7 @@ tests/test_notebooks.py,sha256=7HVmYiytsz0QIJ11iRkGGs4_hzNjofXAUs_OZou3Gm0,301
179
179
  tests/test_partial_install.py,sha256=G69-GNcJ9YNgs6K2bVTEZO0Jpb14xMRQWTm8A6VuIco,2841
180
180
  tests/test_preprocessing.py,sha256=c0rKS9d5h37uDcV7fVOTnn5GMVbEB84b8ZTCTdRmvFs,1422
181
181
  tests/test_segmentation.py,sha256=k1b_zIZdlytEdJcHjAUQEO3gTBAHtv5WvrwQN2xD4kc,3470
182
- tests/test_signals.py,sha256=DWDRGpw_k2VE5pWnqJexsa313YEi8c2KzC51DFzykco,3641
182
+ tests/test_signals.py,sha256=upfhDyQMquOOKuYf7a34TglimHK74oYWQ9RyuK7Mg7c,4285
183
183
  tests/test_tracking.py,sha256=_YLjwQ3EChQssoHDfEnUJ7fI1yC5KEcJsFnAVR64L70,18909
184
184
  tests/test_utils.py,sha256=aSB_eMw9fzTsnxxdYoNmdQQRrXkWqBXB7Uv4TGU6kYE,4778
185
185
  tests/gui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -187,8 +187,9 @@ tests/gui/test_enhancements.py,sha256=3x9au_rkQtMZ94DRj3OaEHKPr511RrWqBAUAcNQn1y
187
187
  tests/gui/test_measure_annotator_bugfix.py,sha256=tPfgWNKC0UkvrVssSrUcVDC1qgpzx6l2yCqvKtKYkM4,4544
188
188
  tests/gui/test_new_project.py,sha256=wRjW2vEaZb0LWT-f8G8-Ptk8CW9z8-FDPLpV5uqj6ck,8778
189
189
  tests/gui/test_project.py,sha256=KzAnodIc0Ovta0ARL5Kr5PkOR5euA6qczT_GhEZpyE4,4710
190
- celldetective-1.5.0b8.dist-info/METADATA,sha256=hUsQY-GrHvD70Htr2XKBXkJlHwv3B4dBe5hQ9sFQonw,11523
191
- celldetective-1.5.0b8.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
192
- celldetective-1.5.0b8.dist-info/entry_points.txt,sha256=2NU6_EOByvPxqBbCvjwxlVlvnQreqZ3BKRCVIKEv3dg,62
193
- celldetective-1.5.0b8.dist-info/top_level.txt,sha256=6rsIKKfGMKgud7HPuATcpq6EhdXwcg_yknBVWn9x4C4,20
194
- celldetective-1.5.0b8.dist-info/RECORD,,
190
+ tests/gui/test_spot_detection_viewer.py,sha256=g-Lyi1sJNWCDy3gPkRU0RlP1BJaOJ6Gg3Ouy0cX_F3Y,6415
191
+ celldetective-1.5.0b9.dist-info/METADATA,sha256=-Vdw3UnjUJDidGKCCb8Z_5EcQ9Z4TUj35w5KYx6z1x4,11523
192
+ celldetective-1.5.0b9.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
193
+ celldetective-1.5.0b9.dist-info/entry_points.txt,sha256=2NU6_EOByvPxqBbCvjwxlVlvnQreqZ3BKRCVIKEv3dg,62
194
+ celldetective-1.5.0b9.dist-info/top_level.txt,sha256=6rsIKKfGMKgud7HPuATcpq6EhdXwcg_yknBVWn9x4C4,20
195
+ celldetective-1.5.0b9.dist-info/RECORD,,
@@ -0,0 +1,187 @@
1
+ import pytest
2
+ import numpy as np
3
+ import logging
4
+ from PyQt5.QtWidgets import QApplication
5
+ from celldetective.gui.viewers.spot_detection_viewer import SpotDetectionVisualizer
6
+ from celldetective.gui.gui_utils import PreprocessingLayout2
7
+ from unittest.mock import MagicMock, patch
8
+
9
+
10
+ @pytest.fixture(autouse=True)
11
+ def disable_logging():
12
+ """Disable all logging to avoid Windows OSError with pytest capture."""
13
+ logger = logging.getLogger()
14
+ try:
15
+ logging.disable(logging.CRITICAL)
16
+ yield
17
+ finally:
18
+ logging.disable(logging.NOTSET)
19
+
20
+
21
+ @pytest.fixture
22
+ def dummy_data():
23
+ """
24
+ Create a dummy stack: 5 frames, 100x100 pixels, 2 channels.
25
+ Channel 0: Clean background (zeros)
26
+ Channel 1: Two Gaussian spots with high intensity
27
+ """
28
+ frames = 5
29
+ y, x = 100, 100
30
+ channels = 2
31
+
32
+ stack = np.zeros((frames, y, x, channels), dtype=np.float32)
33
+
34
+ # Create coordinate grids
35
+ Y, X = np.ogrid[:y, :x]
36
+
37
+ # Gaussian spot 1 at (22, 22) - center of mask 1
38
+ center_y1, center_x1 = 22, 22
39
+ sigma = 2.0
40
+ gaussian1 = np.exp(-((Y - center_y1) ** 2 + (X - center_x1) ** 2) / (2 * sigma**2))
41
+
42
+ # Gaussian spot 2 at (62, 62) - center of mask 2
43
+ center_y2, center_x2 = 62, 62
44
+ gaussian2 = np.exp(-((Y - center_y2) ** 2 + (X - center_x2) ** 2) / (2 * sigma**2))
45
+
46
+ # Add to stack with high intensity (1000 for spot 1, 800 for spot 2)
47
+ spots_frame = (gaussian1 * 1000 + gaussian2 * 800).astype(np.float32)
48
+ for f in range(frames):
49
+ stack[f, :, :, 1] = spots_frame
50
+
51
+ # Channel 0 stays at zero (clean background)
52
+
53
+ # Create dummy masks (labels) - each spot is inside its own cell
54
+ masks = np.zeros((frames, y, x), dtype=np.uint16)
55
+ masks[:, 15:30, 15:30] = 1 # Mask around Spot 1 (22, 22)
56
+ masks[:, 55:70, 55:70] = 2 # Mask around Spot 2 (62, 62)
57
+
58
+ return stack, masks
59
+
60
+
61
+ def test_spot_detection_visualizer_interactions(qtbot, dummy_data):
62
+ """
63
+ Test interactions with SpotDetectionVisualizer.
64
+ """
65
+ stack, labels = dummy_data
66
+ channel_names = ["Background", "Spots"]
67
+
68
+ # Mock parent widgets that might be updated by the visualizer
69
+ parent_channel_cb = MagicMock()
70
+ parent_diameter_le = MagicMock()
71
+ parent_threshold_le = MagicMock()
72
+ parent_preprocessing_list = MagicMock()
73
+
74
+ viewer = SpotDetectionVisualizer(
75
+ stack=stack,
76
+ labels=labels,
77
+ channel_names=channel_names,
78
+ n_channels=2,
79
+ parent_channel_cb=parent_channel_cb,
80
+ parent_diameter_le=parent_diameter_le,
81
+ parent_threshold_le=parent_threshold_le,
82
+ parent_preprocessing_list=parent_preprocessing_list,
83
+ window_title="Test Spot Detective",
84
+ channel_cb=True,
85
+ contrast_slider=False,
86
+ frame_slider=False,
87
+ )
88
+
89
+ qtbot.addWidget(viewer)
90
+ viewer.show()
91
+ qtbot.waitForWindowShown(viewer)
92
+
93
+ # 1. Test Channel Selection
94
+ # Default is target_channel=0 (Background)
95
+ assert viewer.detection_channel == 0
96
+
97
+ # Switch to Spots channel (Index 1)
98
+ viewer.detection_channel_cb.setCurrentIndex(1)
99
+ assert viewer.detection_channel == 1
100
+
101
+ # Force frame update to ensure target_img is correct for channel 1
102
+ viewer.change_frame(0)
103
+
104
+ # Verify image updated to Channel 1, Frame 0
105
+ current_img = viewer.target_img
106
+ expected_img = stack[0, :, :, 1]
107
+ np.testing.assert_array_equal(current_img, expected_img)
108
+
109
+ # 2. Test Spot Detection Parameters
110
+ # Set Diameter (LoG works best with diameter ~ 2*sqrt(2)*sigma ~ 5.6 for sigma=2)
111
+ viewer.spot_diam_le.clear()
112
+ qtbot.keyClicks(viewer.spot_diam_le, "4")
113
+ assert viewer.spot_diam_le.text() == "4"
114
+
115
+ # Set Threshold (low threshold to ensure detection)
116
+ viewer.spot_thresh_le.clear()
117
+ qtbot.keyClicks(viewer.spot_thresh_le, "0.01")
118
+ assert viewer.spot_thresh_le.text() == "0.01"
119
+
120
+ # Manually trigger control_valid_parameters to update self.diameter and self.thresh
121
+ viewer.control_valid_parameters()
122
+
123
+ # Verify parameters were set
124
+ assert viewer.diameter == 4.0
125
+ assert viewer.thresh == 0.01
126
+
127
+ # Trigger detection by clicking apply button
128
+ qtbot.mouseClick(viewer.apply_diam_btn, 1) # Qt.LeftButton = 1
129
+ qtbot.wait(200) # Wait for detection to complete
130
+
131
+ # Check that we recovered 2 spots
132
+ # In dummy_data: Spot 1 at (22, 22), Spot 2 at (62, 62)
133
+ n_spots = (
134
+ len(viewer.spot_positions)
135
+ if hasattr(viewer, "spot_positions") and viewer.spot_positions is not None
136
+ else 0
137
+ )
138
+ assert (
139
+ n_spots == 2
140
+ ), f"Expected 2 spots, found {n_spots}. Positions: {viewer.spot_positions if hasattr(viewer, 'spot_positions') else 'N/A'}"
141
+
142
+ # Verify positions roughly match (22, 22) and (62, 62)
143
+ # spot_positions are (x, y) pairs
144
+ pos = viewer.spot_positions
145
+ has_spot_1 = np.any(np.all(np.abs(pos - [22, 22]) < 5, axis=1))
146
+ has_spot_2 = np.any(np.all(np.abs(pos - [62, 62]) < 5, axis=1))
147
+ assert has_spot_1, f"Spot 1 not found near (22, 22). Positions: {pos}"
148
+ assert has_spot_2, f"Spot 2 not found near (62, 62). Positions: {pos}"
149
+
150
+ # 3. Test Preprocessing and Preview
151
+ # Ensure preview is unchecked initially
152
+ assert not viewer.preview_cb.isChecked()
153
+
154
+ # Check "Preview" - should show original image if filter list is empty
155
+ viewer.preview_cb.setChecked(True)
156
+ assert viewer.preview_cb.isChecked()
157
+ # Image should still match original target since no filters
158
+ np.testing.assert_array_equal(viewer.im.get_array(), expected_img)
159
+
160
+ # Add a filter: "gauss" with sigma=2
161
+ # Directly manipulate the list since dialog interaction is complex
162
+ viewer.preprocessing.list.items.append(["gauss", 2])
163
+ viewer.preprocessing.list.list_widget.addItems(["gauss_filter"])
164
+
165
+ # Force preview update
166
+ viewer.update_preview_if_active()
167
+ qtbot.wait(200)
168
+
169
+ preview_img = viewer.im.get_array()
170
+ assert not np.array_equal(
171
+ preview_img, expected_img
172
+ ), "Preview image should differ after adding gaussian filter"
173
+
174
+ # 4. Remove Filter
175
+ # Select item 0
176
+ viewer.preprocessing.list.list_widget.setCurrentRow(0)
177
+ # Click remove button
178
+ viewer.preprocessing.delete_filter_btn.click()
179
+
180
+ qtbot.wait(200)
181
+
182
+ # Internal items should be empty
183
+ assert len(viewer.preprocessing.list.items) == 0
184
+
185
+ # Preview should revert to original
186
+ reverted_img = viewer.im.get_array()
187
+ np.testing.assert_array_equal(reverted_img, expected_img)
tests/test_signals.py CHANGED
@@ -1,135 +1,154 @@
1
1
  import unittest
2
- import matplotlib.pyplot as plt
3
2
  import numpy as np
4
3
  import os
5
4
  import random
6
5
  import pandas as pd
7
6
  import shutil
8
7
 
9
- def sigmoid(t,t0,dt,A,offset):
10
- return A/(1+np.exp(-(t-t0)/dt)) + offset
8
+
9
+ def sigmoid(t, t0, dt, A, offset):
10
+ return A / (1 + np.exp(-(t - t0) / dt)) + offset
11
+
11
12
 
12
13
  def generate_fake_signal_data(n_signals):
13
-
14
- timeline = np.linspace(0,100,100)
15
- amplitudes = list(np.linspace(2000,3000,100))
16
- slopes = list(np.linspace(0.5,5,100))
17
- means = list(np.linspace(-100,200,100))
18
- random_cut = list(np.linspace(25,200,176,dtype=int))
19
- noise_levels = list(np.linspace(1,100,100,dtype=int))
20
-
21
- trajectories = []
22
- for i in range(n_signals):
23
-
24
- a = random.sample(amplitudes,k=1)[0]
25
- dt = random.sample(slopes,k=1)[0]
26
- mu = random.sample(means,k=1)[0]
27
- cut = random.sample(random_cut,k=1)[0]
28
- n = random.sample(noise_levels,k=1)[0]
29
-
30
- if mu<=0.:
31
- cclass=2
32
- t0=-1
33
- elif (mu>0)*(mu<=100):
34
- cclass=0
35
- t0=mu
36
- else:
37
- cclass=1
38
- t0=-1
39
-
40
- noise = [random.random()*n for i in range(len(timeline))]
41
- signal = sigmoid(timeline, mu, dt,a,0)+noise
42
- signal = signal[:cut]
43
- if mu>=cut:
44
- cclass=1
45
- t0=-1
46
-
47
- for j in range(len(signal)):
48
- trajectories.append({'TRACK_ID': i, 'POSITION_X': 0., 'POSITION_Y': 0., 'FRAME': j,'signal': signal[j], 't0': t0, 'cclass': cclass})
49
-
50
- trajectories = pd.DataFrame(trajectories)
51
-
52
- return trajectories
53
-
54
- def export_set(trajectories, name='set.npy', output_folder='.'):
55
-
56
- training_set = []
57
- cols = trajectories.columns
58
- tracks = np.unique(trajectories["TRACK_ID"].to_numpy())
59
-
60
- for track in tracks:
61
- signals = {}
62
- for c in cols:
63
- signals.update({c: trajectories.loc[trajectories["TRACK_ID"] == track, c].to_numpy()})
64
- time_of_interest = trajectories.loc[trajectories["TRACK_ID"] == track, "t0"].to_numpy()[0]
65
- cclass = trajectories.loc[trajectories["TRACK_ID"] == track, "cclass"].to_numpy()[0]
66
- signals.update({"time_of_interest": time_of_interest, "class": cclass})
67
- training_set.append(signals)
68
-
69
- np.save(os.sep.join([output_folder,name]), training_set)
14
+
15
+ timeline = np.linspace(0, 100, 100)
16
+ amplitudes = list(np.linspace(2000, 3000, 100))
17
+ slopes = list(np.linspace(0.5, 5, 100))
18
+ means = list(np.linspace(-100, 200, 100))
19
+ random_cut = list(np.linspace(25, 200, 176, dtype=int))
20
+ noise_levels = list(np.linspace(1, 100, 100, dtype=int))
21
+
22
+ trajectories = []
23
+ for i in range(n_signals):
24
+
25
+ a = random.sample(amplitudes, k=1)[0]
26
+ dt = random.sample(slopes, k=1)[0]
27
+ mu = random.sample(means, k=1)[0]
28
+ cut = random.sample(random_cut, k=1)[0]
29
+ n = random.sample(noise_levels, k=1)[0]
30
+
31
+ if mu <= 0.0:
32
+ cclass = 2
33
+ t0 = -1
34
+ elif (mu > 0) * (mu <= 100):
35
+ cclass = 0
36
+ t0 = mu
37
+ else:
38
+ cclass = 1
39
+ t0 = -1
40
+
41
+ noise = [random.random() * n for i in range(len(timeline))]
42
+ signal = sigmoid(timeline, mu, dt, a, 0) + noise
43
+ signal = signal[:cut]
44
+ if mu >= cut:
45
+ cclass = 1
46
+ t0 = -1
47
+
48
+ for j in range(len(signal)):
49
+ trajectories.append(
50
+ {
51
+ "TRACK_ID": i,
52
+ "POSITION_X": 0.0,
53
+ "POSITION_Y": 0.0,
54
+ "FRAME": j,
55
+ "signal": signal[j],
56
+ "t0": t0,
57
+ "cclass": cclass,
58
+ }
59
+ )
60
+
61
+ trajectories = pd.DataFrame(trajectories)
62
+
63
+ return trajectories
64
+
65
+
66
+ def export_set(trajectories, name="set.npy", output_folder="."):
67
+
68
+ training_set = []
69
+ cols = trajectories.columns
70
+ tracks = np.unique(trajectories["TRACK_ID"].to_numpy())
71
+
72
+ for track in tracks:
73
+ signals = {}
74
+ for c in cols:
75
+ signals.update(
76
+ {c: trajectories.loc[trajectories["TRACK_ID"] == track, c].to_numpy()}
77
+ )
78
+ time_of_interest = trajectories.loc[
79
+ trajectories["TRACK_ID"] == track, "t0"
80
+ ].to_numpy()[0]
81
+ cclass = trajectories.loc[
82
+ trajectories["TRACK_ID"] == track, "cclass"
83
+ ].to_numpy()[0]
84
+ signals.update({"time_of_interest": time_of_interest, "class": cclass})
85
+ training_set.append(signals)
86
+
87
+ np.save(os.sep.join([output_folder, name]), training_set)
70
88
 
71
89
 
72
90
  class TestCreateSignalModel(unittest.TestCase):
73
91
 
74
- def test_create_model(self):
92
+ def test_create_model(self):
75
93
 
76
- from celldetective.event_detection_models import SignalDetectionModel
94
+ from celldetective.event_detection_models import SignalDetectionModel
77
95
 
78
96
  model = SignalDetectionModel(
79
- channel_option=["signal"],
80
- model_signal_length=128,
81
- n_channels=1,
82
- n_conv=2,
83
- n_classes=3,
84
- dense_collection=512,
85
- dropout_rate=0.1,
86
- label='test',
87
- )
97
+ channel_option=["signal"],
98
+ model_signal_length=128,
99
+ n_channels=1,
100
+ n_conv=2,
101
+ n_classes=3,
102
+ dense_collection=512,
103
+ dropout_rate=0.1,
104
+ label="test",
105
+ )
88
106
 
89
107
 
90
108
  class TestTrainSignalModel(unittest.TestCase):
91
109
 
92
- @classmethod
93
- def setUpClass(self):
110
+ @classmethod
111
+ def setUpClass(self):
94
112
 
95
- from celldetective.event_detection_models import SignalDetectionModel
113
+ from celldetective.event_detection_models import SignalDetectionModel
96
114
 
97
115
  self.trajectories = generate_fake_signal_data(300)
98
- if not os.path.exists('temp'):
99
- os.mkdir('temp')
100
- export_set(self.trajectories, name='set.npy', output_folder='temp')
101
- self.model = SignalDetectionModel(
102
- channel_option=["signal"],
103
- model_signal_length=128,
104
- n_channels=1,
105
- n_conv=2,
106
- n_classes=3,
107
- dense_collection=512,
108
- dropout_rate=0.1,
109
- label='test',
110
- )
111
-
112
- def test_train_signal_model(self):
113
-
114
- self.model.fit_from_directory(
115
- ['temp'],
116
- normalize=True,
117
- normalization_percentile=None,
118
- normalization_values = None,
119
- normalization_clip = None,
120
- channel_option=["signal"],
121
- target_directory='temp',
122
- augment=False,
123
- model_name='None',
124
- validation_split=0.2,
125
- test_split=0.1,
126
- batch_size = 16,
127
- epochs=1,
128
- recompile_pretrained=False,
129
- learning_rate=0.01,
130
- show_plots=False,
131
- )
132
- shutil.rmtree('temp')
133
-
134
- if __name__=="__main__":
135
- unittest.main()
116
+ if not os.path.exists("temp"):
117
+ os.mkdir("temp")
118
+ export_set(self.trajectories, name="set.npy", output_folder="temp")
119
+ self.model = SignalDetectionModel(
120
+ channel_option=["signal"],
121
+ model_signal_length=128,
122
+ n_channels=1,
123
+ n_conv=2,
124
+ n_classes=3,
125
+ dense_collection=512,
126
+ dropout_rate=0.1,
127
+ label="test",
128
+ )
129
+
130
+ def test_train_signal_model(self):
131
+
132
+ self.model.fit_from_directory(
133
+ ["temp"],
134
+ normalize=True,
135
+ normalization_percentile=None,
136
+ normalization_values=None,
137
+ normalization_clip=None,
138
+ channel_option=["signal"],
139
+ target_directory="temp",
140
+ augment=False,
141
+ model_name="None",
142
+ validation_split=0.2,
143
+ test_split=0.1,
144
+ batch_size=16,
145
+ epochs=1,
146
+ recompile_pretrained=False,
147
+ learning_rate=0.01,
148
+ show_plots=False,
149
+ )
150
+ shutil.rmtree("temp")
151
+
152
+
153
+ if __name__ == "__main__":
154
+ unittest.main()