small-fish-gui 1.7.1__py3-none-any.whl → 1.8.1__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.
- small_fish_gui/__init__.py +1 -1
- small_fish_gui/batch/integrity.py +3 -3
- small_fish_gui/batch/pipeline.py +14 -6
- small_fish_gui/batch/prompt.py +14 -14
- small_fish_gui/batch/update.py +2 -2
- small_fish_gui/batch/utils.py +8 -8
- small_fish_gui/batch/values.txt +2 -2
- small_fish_gui/gui/help_module.py +4 -4
- small_fish_gui/gui/layout.py +24 -20
- small_fish_gui/gui/prompts.py +99 -51
- small_fish_gui/hints.py +54 -0
- small_fish_gui/interface/__init__.py +1 -1
- small_fish_gui/interface/image.py +2 -2
- small_fish_gui/interface/{output.py → inoutput.py} +39 -0
- small_fish_gui/interface/testing.py +10 -6
- small_fish_gui/pipeline/__init__.py +4 -4
- small_fish_gui/pipeline/_colocalisation.py +19 -14
- small_fish_gui/pipeline/_preprocess.py +98 -50
- small_fish_gui/pipeline/actions.py +142 -38
- small_fish_gui/pipeline/detection.py +54 -106
- small_fish_gui/pipeline/main.py +28 -35
- small_fish_gui/pipeline/{_segmentation.py → segmentation.py} +32 -14
- small_fish_gui/pipeline/spots.py +4 -1
- {small_fish_gui-1.7.1.dist-info → small_fish_gui-1.8.1.dist-info}/METADATA +1 -2
- small_fish_gui-1.8.1.dist-info/RECORD +50 -0
- {small_fish_gui-1.7.1.dist-info → small_fish_gui-1.8.1.dist-info}/WHEEL +1 -1
- small_fish_gui/batch/output.py +0 -0
- small_fish_gui/batch/values.py +0 -3
- small_fish_gui/docs/conf.py +0 -1
- small_fish_gui/interface/parameters.py +0 -2
- small_fish_gui-1.7.1.dist-info/RECORD +0 -53
- /small_fish_gui/gui/{general_help_screenshot.png → screenshot/general_help_screenshot.png} +0 -0
- /small_fish_gui/gui/{mapping_help_screenshot.png → screenshot/mapping_help_screenshot.png} +0 -0
- /small_fish_gui/gui/{segmentation_help_screenshot.png → screenshot/segmentation_help_screenshot.png} +0 -0
- {small_fish_gui-1.7.1.dist-info → small_fish_gui-1.8.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -2,59 +2,77 @@
|
|
|
2
2
|
This submodule groups all the possible actions of the user in the main windows. It is the start of each action the user can do.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
-
from ..gui.prompts import output_image_prompt,
|
|
6
|
-
from ..
|
|
7
|
-
from .
|
|
8
|
-
|
|
9
|
-
from .
|
|
10
|
-
from .
|
|
5
|
+
from ..gui.prompts import output_image_prompt, prompt_save_segmentation, prompt_load_segmentation
|
|
6
|
+
from ..gui.prompts import ask_detection_confirmation, ask_cancel_detection, ask_confirmation
|
|
7
|
+
from ..gui.prompts import rename_prompt
|
|
8
|
+
|
|
9
|
+
from ..interface.inoutput import write_results
|
|
10
|
+
from ..interface.inoutput import input_segmentation, output_segmentation
|
|
11
|
+
|
|
12
|
+
from ._preprocess import map_channels
|
|
13
|
+
from ._preprocess import prepare_image_detection
|
|
14
|
+
from ._preprocess import reorder_shape, reorder_image_stack
|
|
15
|
+
from ._preprocess import ask_input_parameters
|
|
16
|
+
|
|
17
|
+
from .detection import initiate_detection, launch_detection, launch_features_computation
|
|
18
|
+
from .detection import get_nucleus_signal
|
|
11
19
|
from .spots import launch_spots_extraction
|
|
12
20
|
|
|
21
|
+
from .segmentation import launch_segmentation
|
|
22
|
+
from ._colocalisation import initiate_colocalisation, launch_colocalisation
|
|
23
|
+
|
|
24
|
+
from ..hints import pipeline_parameters
|
|
25
|
+
|
|
26
|
+
import os
|
|
13
27
|
import pandas as pd
|
|
14
28
|
import PySimpleGUI as sg
|
|
29
|
+
import numpy as np
|
|
30
|
+
|
|
31
|
+
def segment_cells(user_parameters : pipeline_parameters, nucleus_label, cytoplasm_label) :
|
|
32
|
+
if user_parameters['segmentation_done'] :
|
|
33
|
+
if ask_confirmation("A segmentation is in small fish memory, do you want to erase it ? (you will not be able to undo)") :
|
|
34
|
+
user_parameters['segmentation_done'] = False
|
|
35
|
+
nucleus_label = None
|
|
36
|
+
cytoplasm_label = None
|
|
37
|
+
else :
|
|
38
|
+
return nucleus_label, cytoplasm_label, user_parameters
|
|
39
|
+
|
|
40
|
+
nucleus_label, cytoplasm_label, user_parameters = launch_segmentation(
|
|
41
|
+
user_parameters,
|
|
42
|
+
nucleus_label=nucleus_label,
|
|
43
|
+
cytoplasm_label=cytoplasm_label,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
if type(cytoplasm_label) != type(None) and type(nucleus_label) != type(None) :
|
|
47
|
+
user_parameters['segmentation_done'] = True
|
|
15
48
|
|
|
16
|
-
|
|
49
|
+
return nucleus_label, cytoplasm_label, user_parameters
|
|
50
|
+
|
|
51
|
+
def add_detection(user_parameters : pipeline_parameters, acquisition_id, cytoplasm_label, nucleus_label) :
|
|
17
52
|
"""
|
|
18
|
-
#TODO :
|
|
53
|
+
#TODO : Separate segmentation from detection in pipeline.
|
|
19
54
|
"""
|
|
20
55
|
|
|
21
56
|
new_results_df = pd.DataFrame()
|
|
22
57
|
new_cell_results_df = pd.DataFrame()
|
|
23
58
|
|
|
24
59
|
#Ask for image parameters
|
|
25
|
-
new_parameters = ask_input_parameters(ask_for_segmentation=
|
|
60
|
+
new_parameters = ask_input_parameters(ask_for_segmentation= False) #The image is open and stored inside user_parameters
|
|
26
61
|
if type(new_parameters) == type(None) : #if user clicks 'Cancel'
|
|
27
|
-
return new_results_df, new_cell_results_df, acquisition_id, user_parameters
|
|
62
|
+
return new_results_df, new_cell_results_df, acquisition_id, user_parameters
|
|
28
63
|
else :
|
|
29
64
|
user_parameters.update(new_parameters)
|
|
30
65
|
|
|
31
|
-
|
|
32
|
-
if type(
|
|
33
|
-
return new_results_df, new_cell_results_df, acquisition_id, user_parameters
|
|
34
|
-
user_parameters['reordered_shape'] = reorder_shape(user_parameters['shape'],
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
#Segmentation
|
|
38
|
-
if user_parameters['Segmentation'] and not segmentation_done:
|
|
39
|
-
im_seg = reorder_image_stack(map, user_parameters)
|
|
40
|
-
cytoplasm_label, nucleus_label, user_parameters = launch_segmentation(im_seg, user_parameters=user_parameters)
|
|
41
|
-
elif segmentation_done :
|
|
42
|
-
pass
|
|
43
|
-
else :
|
|
44
|
-
cytoplasm_label, nucleus_label = None,None
|
|
45
|
-
|
|
46
|
-
if type(cytoplasm_label) == type(None) or type(nucleus_label) == type(None) :
|
|
47
|
-
user_parameters['Segmentation'] = False
|
|
48
|
-
segmentation_done = False
|
|
49
|
-
|
|
50
|
-
else : segmentation_done = True
|
|
66
|
+
map_ = map_channels(user_parameters)
|
|
67
|
+
if type(map_) == type(None) : #User clicks Cancel
|
|
68
|
+
return new_results_df, new_cell_results_df, acquisition_id, user_parameters
|
|
69
|
+
user_parameters['reordered_shape'] = reorder_shape(user_parameters['shape'], map_)
|
|
51
70
|
|
|
52
71
|
#Detection
|
|
53
72
|
while True : # This loop allow user to try detection with different thresholds or parameters before launching features computation
|
|
54
73
|
detection_parameters = initiate_detection(
|
|
55
74
|
user_parameters,
|
|
56
|
-
|
|
57
|
-
map= map,
|
|
75
|
+
map_= map_,
|
|
58
76
|
shape = user_parameters['image'].shape
|
|
59
77
|
)
|
|
60
78
|
|
|
@@ -63,11 +81,11 @@ def add_detection(user_parameters, segmentation_done, acquisition_id, cytoplasm_
|
|
|
63
81
|
else : #If user clicks cancel
|
|
64
82
|
cancel = ask_cancel_detection()
|
|
65
83
|
if cancel :
|
|
66
|
-
return new_results_df, new_cell_results_df, acquisition_id, user_parameters
|
|
84
|
+
return new_results_df, new_cell_results_df, acquisition_id, user_parameters
|
|
67
85
|
else : continue
|
|
68
86
|
|
|
69
87
|
acquisition_id += 1
|
|
70
|
-
image, other_image = prepare_image_detection(
|
|
88
|
+
image, other_image = prepare_image_detection(map_, user_parameters)
|
|
71
89
|
nucleus_signal = get_nucleus_signal(image, other_image, user_parameters)
|
|
72
90
|
|
|
73
91
|
try : # Catch error raised if user enter a spot size too small compare to voxel size
|
|
@@ -87,7 +105,7 @@ def add_detection(user_parameters, segmentation_done, acquisition_id, cytoplasm_
|
|
|
87
105
|
raise(error)
|
|
88
106
|
|
|
89
107
|
|
|
90
|
-
if user_parameters['
|
|
108
|
+
if user_parameters['show_napari_corrector'] :
|
|
91
109
|
if ask_detection_confirmation(user_parameters.get('threshold')) : break
|
|
92
110
|
else :
|
|
93
111
|
break
|
|
@@ -116,7 +134,93 @@ def add_detection(user_parameters, segmentation_done, acquisition_id, cytoplasm_
|
|
|
116
134
|
user_parameters=user_parameters,
|
|
117
135
|
frame_results=frame_result,
|
|
118
136
|
)
|
|
119
|
-
return new_results_df, new_cell_results_df, acquisition_id, user_parameters
|
|
137
|
+
return new_results_df, new_cell_results_df, acquisition_id, user_parameters
|
|
138
|
+
|
|
139
|
+
def save_segmentation(nucleus_label : np.ndarray, cytoplasm_label: np.ndarray) :
|
|
140
|
+
if type(nucleus_label) == type(None) or type(cytoplasm_label) == type(None) :
|
|
141
|
+
sg.popup("No segmentation to save.")
|
|
142
|
+
|
|
143
|
+
else :
|
|
144
|
+
|
|
145
|
+
while True :
|
|
146
|
+
answer = prompt_save_segmentation()
|
|
147
|
+
if type(answer) == type(None) :
|
|
148
|
+
return False #User clicks cancel
|
|
149
|
+
|
|
150
|
+
path = answer['folder'] + '/' + answer['filename']
|
|
151
|
+
is_npy, is_npz, is_npz_compressed = answer['ext'], answer['ext0'], answer['ext1']
|
|
152
|
+
|
|
153
|
+
if is_npy + is_npz + is_npz_compressed == 1 :
|
|
154
|
+
if is_npy :
|
|
155
|
+
extension = 'npy'
|
|
156
|
+
if os.path.isfile(path + '_nucleus_segmentation.npy') or os.path.isfile(path + '_cytoplasm_segmentation.npy') :
|
|
157
|
+
if ask_confirmation("File exists. Replace ?") :
|
|
158
|
+
break
|
|
159
|
+
else :
|
|
160
|
+
pass
|
|
161
|
+
else :
|
|
162
|
+
break
|
|
163
|
+
|
|
164
|
+
elif is_npz :
|
|
165
|
+
extension = 'npz_uncompressed'
|
|
166
|
+
if os.path.isfile(path + '_nucleus_segmentation.npz') or os.path.isfile(path + '_cytoplasm_segmentation.npz') :
|
|
167
|
+
if ask_confirmation("File exists. Replace ?") :
|
|
168
|
+
break
|
|
169
|
+
else :
|
|
170
|
+
pass
|
|
171
|
+
else :
|
|
172
|
+
break
|
|
173
|
+
|
|
174
|
+
elif is_npz_compressed :
|
|
175
|
+
extension = 'npz_compressed'
|
|
176
|
+
if os.path.isfile(path + '_nucleus_segmentation.npz') or os.path.isfile(path + '_cytoplasm_segmentation.npz') :
|
|
177
|
+
if ask_confirmation("File exists. Replace ?") :
|
|
178
|
+
break
|
|
179
|
+
else :
|
|
180
|
+
pass
|
|
181
|
+
else :
|
|
182
|
+
break
|
|
183
|
+
|
|
184
|
+
else :
|
|
185
|
+
sg.popup("Please select an extension.")
|
|
186
|
+
|
|
187
|
+
saved = output_segmentation(
|
|
188
|
+
path,
|
|
189
|
+
extension,
|
|
190
|
+
nucleus_label,
|
|
191
|
+
cytoplasm_label,
|
|
192
|
+
)
|
|
193
|
+
if saved : sg.popup("Segmentation was saved at {0}.".format(path))
|
|
194
|
+
else : sg.popup("No segmentation was saved..")
|
|
195
|
+
return True
|
|
196
|
+
|
|
197
|
+
def load_segmentation(nucleus_label, cytoplasm_label, segmentation_done) :
|
|
198
|
+
|
|
199
|
+
if segmentation_done :
|
|
200
|
+
if ask_confirmation("Segmentation already in memory. Replace ?") :
|
|
201
|
+
pass
|
|
202
|
+
else :
|
|
203
|
+
return nucleus_label, cytoplasm_label, segmentation_done
|
|
204
|
+
|
|
205
|
+
answer = prompt_load_segmentation()
|
|
206
|
+
if type(answer) == type(None) : #user clicks cancel
|
|
207
|
+
return nucleus_label, cytoplasm_label, segmentation_done
|
|
208
|
+
nucleus_label, cytoplasm_label = input_segmentation(
|
|
209
|
+
answer['nucleus'],
|
|
210
|
+
answer['cytoplasm'],
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
if type(nucleus_label) != type(None) and type(nucleus_label) != np.ndarray :
|
|
214
|
+
nucleus_label = nucleus_label['arr_0']
|
|
215
|
+
|
|
216
|
+
if type(cytoplasm_label) != type(None) and type(cytoplasm_label) != np.ndarray :
|
|
217
|
+
cytoplasm_label = cytoplasm_label['arr_0']
|
|
218
|
+
|
|
219
|
+
segmentation_done = (type(nucleus_label) != type(None) and type(cytoplasm_label) != type(None))
|
|
220
|
+
|
|
221
|
+
if segmentation_done : assert type(nucleus_label) == np.ndarray and type(cytoplasm_label) == np.ndarray
|
|
222
|
+
|
|
223
|
+
return nucleus_label, cytoplasm_label, segmentation_done
|
|
120
224
|
|
|
121
225
|
def save_results(result_df, cell_result_df, global_coloc_df, cell_coloc_df) :
|
|
122
226
|
if len(result_df) != 0 :
|
|
@@ -207,14 +311,14 @@ def rename_acquisitions(
|
|
|
207
311
|
|
|
208
312
|
if len(result_df) == 0 :
|
|
209
313
|
sg.popup("No acquisition to rename.")
|
|
210
|
-
return result_df, cell_result_df, global_coloc_df
|
|
314
|
+
return result_df, cell_result_df, global_coloc_df, cell_coloc_df
|
|
211
315
|
|
|
212
316
|
if len(selected_acquisitions) == 0 :
|
|
213
317
|
sg.popup("Please select the acquisitions you would like to rename.")
|
|
214
318
|
|
|
215
319
|
else :
|
|
216
320
|
name = rename_prompt()
|
|
217
|
-
if not name : return result_df, cell_result_df, global_coloc_df #User didn't put a name or canceled
|
|
321
|
+
if not name : return result_df, cell_result_df, global_coloc_df, cell_coloc_df #User didn't put a name or canceled
|
|
218
322
|
name : str = name.replace(' ','_')
|
|
219
323
|
acquisition_ids = list(result_df.iloc[list(selected_acquisitions)]['acquisition_id'])
|
|
220
324
|
old_names = list(result_df.loc[result_df['acquisition_id'].isin(acquisition_ids)]['name'])
|
|
@@ -1,23 +1,25 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Contains code to handle detection as well as bigfish wrappers related to spot detection.
|
|
3
3
|
"""
|
|
4
|
+
from ..hints import pipeline_parameters
|
|
5
|
+
|
|
4
6
|
|
|
5
7
|
from ._preprocess import ParameterInputError
|
|
6
8
|
from ._preprocess import check_integrity, convert_parameters_types
|
|
7
|
-
|
|
9
|
+
|
|
8
10
|
from ..gui.napari import correct_spots, _update_clusters, threshold_selection
|
|
9
11
|
from ..gui import add_default_loading
|
|
10
|
-
from ..gui import detection_parameters_promt
|
|
12
|
+
from ..gui import detection_parameters_promt
|
|
13
|
+
|
|
11
14
|
from ..utils import compute_anisotropy_coef
|
|
12
|
-
from .
|
|
15
|
+
from ._signaltonoise import compute_snr_spots
|
|
16
|
+
|
|
13
17
|
from magicgui import magicgui
|
|
14
|
-
from napari.layers import Image, Points
|
|
15
18
|
from napari.types import LayerDataTuple
|
|
16
19
|
|
|
17
20
|
import numpy as np
|
|
18
21
|
import pandas as pd
|
|
19
22
|
import PySimpleGUI as sg
|
|
20
|
-
import os
|
|
21
23
|
from numpy import NaN
|
|
22
24
|
import bigfish.detection as detection
|
|
23
25
|
import bigfish.stack as stack
|
|
@@ -29,66 +31,6 @@ from skimage.measure import regionprops
|
|
|
29
31
|
from scipy.ndimage import binary_dilation
|
|
30
32
|
|
|
31
33
|
|
|
32
|
-
def ask_input_parameters(ask_for_segmentation=True) :
|
|
33
|
-
"""
|
|
34
|
-
Prompt user with interface allowing parameters setting for bigFish detection / deconvolution.
|
|
35
|
-
|
|
36
|
-
Keys :
|
|
37
|
-
- 'image path'
|
|
38
|
-
- '3D stack'
|
|
39
|
-
- 'time stack'
|
|
40
|
-
- 'multichannel'
|
|
41
|
-
- 'Dense regions deconvolution'
|
|
42
|
-
- 'Segmentation
|
|
43
|
-
- 'Napari correction'
|
|
44
|
-
- 'threshold'
|
|
45
|
-
- 'time step'
|
|
46
|
-
- 'channel to compute'
|
|
47
|
-
- 'alpha'
|
|
48
|
-
- 'beta'
|
|
49
|
-
- 'gamma'
|
|
50
|
-
- 'voxel_size_{(z,y,x)}'
|
|
51
|
-
- 'spot_size{(z,y,x)}'
|
|
52
|
-
- 'log_kernel_size{(z,y,x)}'
|
|
53
|
-
- 'minimum_distance{(z,y,x)}'
|
|
54
|
-
"""
|
|
55
|
-
|
|
56
|
-
values = {}
|
|
57
|
-
image_input_values = {}
|
|
58
|
-
while True :
|
|
59
|
-
is_3D_preset = image_input_values.setdefault('3D stack', False)
|
|
60
|
-
is_time_preset = image_input_values.setdefault('time stack', False)
|
|
61
|
-
is_multichannel_preset = image_input_values.setdefault('multichannel', False)
|
|
62
|
-
denseregion_preset = image_input_values.setdefault('Dense regions deconvolution', False)
|
|
63
|
-
do_clustering_preset = image_input_values.setdefault('Cluster computation', False)
|
|
64
|
-
do_segmentation_preset = image_input_values.setdefault('Segmentation', False)
|
|
65
|
-
do_napari_preset = image_input_values.setdefault('Napari correction', False)
|
|
66
|
-
|
|
67
|
-
image_input_values = input_image_prompt(
|
|
68
|
-
is_3D_stack_preset=is_3D_preset,
|
|
69
|
-
time_stack_preset=is_time_preset,
|
|
70
|
-
multichannel_preset=is_multichannel_preset,
|
|
71
|
-
do_dense_regions_deconvolution_preset=denseregion_preset,
|
|
72
|
-
do_clustering_preset= do_clustering_preset,
|
|
73
|
-
do_segmentation_preset=do_segmentation_preset,
|
|
74
|
-
do_Napari_correction=do_napari_preset,
|
|
75
|
-
ask_for_segmentation= ask_for_segmentation
|
|
76
|
-
)
|
|
77
|
-
if type(image_input_values) == type(None) :
|
|
78
|
-
return image_input_values
|
|
79
|
-
|
|
80
|
-
if 'image' in image_input_values.keys() :
|
|
81
|
-
image_input_values['shape'] = image_input_values['image'].shape
|
|
82
|
-
break
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
values.update(image_input_values)
|
|
86
|
-
values['dim'] = 3 if values['3D stack'] else 2
|
|
87
|
-
values['filename'] = os.path.basename(values['image path'])
|
|
88
|
-
if values['Segmentation'] and values['time stack'] : sg.popup('Segmentation is not supported for time stack. Segmentation will be turned off.')
|
|
89
|
-
|
|
90
|
-
return values
|
|
91
|
-
|
|
92
34
|
|
|
93
35
|
def compute_auto_threshold(images, voxel_size=None, spot_radius=None, log_kernel_size=None, minimum_distance=None, im_number= 15, crop_zstack= None) :
|
|
94
36
|
"""
|
|
@@ -262,38 +204,38 @@ def cluster_detection(spots, voxel_size, radius = 350, nb_min_spots = 4, keys_to
|
|
|
262
204
|
|
|
263
205
|
return res
|
|
264
206
|
|
|
265
|
-
def initiate_detection(user_parameters
|
|
266
|
-
is_3D_stack= user_parameters['
|
|
267
|
-
is_multichannel = user_parameters['
|
|
268
|
-
do_dense_region_deconvolution = user_parameters['
|
|
269
|
-
do_clustering = user_parameters['
|
|
270
|
-
|
|
207
|
+
def initiate_detection(user_parameters : pipeline_parameters, map_, shape) :
|
|
208
|
+
is_3D_stack= user_parameters['is_3D_stack']
|
|
209
|
+
is_multichannel = user_parameters['is_multichannel']
|
|
210
|
+
do_dense_region_deconvolution = user_parameters['do_dense_regions_deconvolution']
|
|
211
|
+
do_clustering = user_parameters['do_cluster_computation']
|
|
212
|
+
detection_parameters = user_parameters.copy()
|
|
271
213
|
|
|
272
214
|
while True :
|
|
273
|
-
|
|
215
|
+
detection_parameters = detection_parameters_promt(
|
|
274
216
|
is_3D_stack=is_3D_stack,
|
|
275
217
|
is_multichannel=is_multichannel,
|
|
276
218
|
do_dense_region_deconvolution=do_dense_region_deconvolution,
|
|
277
219
|
do_clustering=do_clustering,
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
default_dict=user_parameters
|
|
220
|
+
segmentation_done= user_parameters['segmentation_done'],
|
|
221
|
+
default_dict=detection_parameters
|
|
281
222
|
)
|
|
282
|
-
if type(
|
|
223
|
+
if type(detection_parameters) == type(None) : return user_parameters
|
|
283
224
|
try :
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
225
|
+
detection_parameters = convert_parameters_types(detection_parameters)
|
|
226
|
+
detection_parameters = check_integrity(
|
|
227
|
+
detection_parameters,
|
|
287
228
|
do_dense_region_deconvolution,
|
|
288
229
|
do_clustering,
|
|
289
230
|
is_multichannel,
|
|
290
|
-
segmentation_done,
|
|
291
|
-
|
|
231
|
+
user_parameters['segmentation_done'],
|
|
232
|
+
map_,
|
|
292
233
|
shape
|
|
293
234
|
)
|
|
294
235
|
except ParameterInputError as error:
|
|
295
236
|
sg.popup(error)
|
|
296
237
|
else :
|
|
238
|
+
user_parameters.update(detection_parameters)
|
|
297
239
|
break
|
|
298
240
|
return user_parameters
|
|
299
241
|
|
|
@@ -311,7 +253,7 @@ def _launch_detection(image, image_input_values: dict) :
|
|
|
311
253
|
spot_size = image_input_values.get('spot_size')
|
|
312
254
|
log_kernel_size = image_input_values.get('log_kernel_size')
|
|
313
255
|
minimum_distance = image_input_values.get('minimum_distance')
|
|
314
|
-
threshold_user_selection = image_input_values
|
|
256
|
+
threshold_user_selection = image_input_values['show_interactive_threshold_selector']
|
|
315
257
|
|
|
316
258
|
if type(threshold) == type(None) :
|
|
317
259
|
threshold = threshold_penalty * compute_auto_threshold(image, voxel_size=voxel_size, spot_radius=spot_size, log_kernel_size=log_kernel_size, minimum_distance=minimum_distance)
|
|
@@ -446,11 +388,11 @@ def _compute_cell_snr(image: np.ndarray, bbox, spots, voxel_size, spot_size) :
|
|
|
446
388
|
return snr_dict
|
|
447
389
|
|
|
448
390
|
@add_default_loading
|
|
449
|
-
def launch_cell_extraction(acquisition_id, spots, clusters, image, nucleus_signal, cell_label, nucleus_label, user_parameters) :
|
|
391
|
+
def launch_cell_extraction(acquisition_id, spots, clusters, image, nucleus_signal, cell_label, nucleus_label, user_parameters : pipeline_parameters) :
|
|
450
392
|
|
|
451
393
|
#Extract parameters
|
|
452
394
|
dim = user_parameters['dim']
|
|
453
|
-
do_clustering = user_parameters['
|
|
395
|
+
do_clustering = user_parameters['do_cluster_computation']
|
|
454
396
|
voxel_size = user_parameters['voxel_size']
|
|
455
397
|
|
|
456
398
|
if do_clustering : other_coords = {'clusters_coords' : clusters} if len(clusters) > 0 else None
|
|
@@ -579,7 +521,7 @@ def launch_cell_extraction(acquisition_id, spots, clusters, image, nucleus_signa
|
|
|
579
521
|
return result_frame
|
|
580
522
|
|
|
581
523
|
@add_default_loading
|
|
582
|
-
def launch_clustering(spots, user_parameters):
|
|
524
|
+
def launch_clustering(spots, user_parameters : pipeline_parameters):
|
|
583
525
|
|
|
584
526
|
voxel_size = user_parameters['voxel_size']
|
|
585
527
|
nb_min_spots = user_parameters['min number of spots']
|
|
@@ -624,8 +566,8 @@ def launch_detection(
|
|
|
624
566
|
'threshold'
|
|
625
567
|
"""
|
|
626
568
|
fov_result = {}
|
|
627
|
-
do_dense_region_deconvolution = user_parameters['
|
|
628
|
-
do_clustering = user_parameters['
|
|
569
|
+
do_dense_region_deconvolution = user_parameters['do_dense_regions_deconvolution']
|
|
570
|
+
do_clustering = user_parameters['do_cluster_computation']
|
|
629
571
|
|
|
630
572
|
spots, threshold = _launch_detection(image, user_parameters, hide_loading = hide_loading)
|
|
631
573
|
|
|
@@ -640,7 +582,7 @@ def launch_detection(
|
|
|
640
582
|
|
|
641
583
|
user_parameters['threshold'] = threshold
|
|
642
584
|
|
|
643
|
-
if user_parameters['
|
|
585
|
+
if user_parameters['show_napari_corrector'] :
|
|
644
586
|
|
|
645
587
|
spots, clusters = correct_spots(
|
|
646
588
|
image,
|
|
@@ -659,11 +601,10 @@ def launch_detection(
|
|
|
659
601
|
return user_parameters, fov_result, spots, clusters
|
|
660
602
|
|
|
661
603
|
|
|
662
|
-
def launch_features_computation(acquisition_id, image, nucleus_signal, spots, clusters, nucleus_label, cell_label, user_parameters, frame_results) :
|
|
604
|
+
def launch_features_computation(acquisition_id, image, nucleus_signal, spots, clusters, nucleus_label, cell_label, user_parameters :pipeline_parameters, frame_results) :
|
|
663
605
|
|
|
664
606
|
dim = image.ndim
|
|
665
|
-
|
|
666
|
-
if user_parameters['Cluster computation'] :
|
|
607
|
+
if user_parameters['do_cluster_computation'] :
|
|
667
608
|
frame_results['cluster_number'] = len(clusters)
|
|
668
609
|
if dim == 3 :
|
|
669
610
|
frame_results['total_spots_in_clusters'] = clusters.sum(axis=0)[3] if len(clusters) >0 else 0
|
|
@@ -671,16 +612,22 @@ def launch_features_computation(acquisition_id, image, nucleus_signal, spots, cl
|
|
|
671
612
|
frame_results['total_spots_in_clusters'] = clusters.sum(axis=0)[2] if len(clusters) >0 else 0
|
|
672
613
|
|
|
673
614
|
if type(cell_label) != type(None) and type(nucleus_label) != type(None):
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
615
|
+
|
|
616
|
+
try :
|
|
617
|
+
cell_result_dframe = launch_cell_extraction(
|
|
618
|
+
acquisition_id=acquisition_id,
|
|
619
|
+
spots=spots,
|
|
620
|
+
clusters=clusters,
|
|
621
|
+
image=image,
|
|
622
|
+
nucleus_signal=nucleus_signal,
|
|
623
|
+
cell_label= cell_label,
|
|
624
|
+
nucleus_label=nucleus_label,
|
|
625
|
+
user_parameters=user_parameters,
|
|
626
|
+
)
|
|
627
|
+
|
|
628
|
+
except IndexError as e: #User loaded a segmentation and no cells can be extracted out of it.
|
|
629
|
+
raise Exception("No cell was fit for quantification in segmentation. This can happen if you loaded empty segmentation or there is a missmatch between cytoplasm and nuclei.\nIf you didn't load segmentation please report the issue as this should not happen.")
|
|
630
|
+
|
|
684
631
|
else :
|
|
685
632
|
cell_result_dframe = pd.DataFrame()
|
|
686
633
|
|
|
@@ -701,10 +648,11 @@ def launch_features_computation(acquisition_id, image, nucleus_signal, spots, cl
|
|
|
701
648
|
cell_result_col = list(cell_result_dframe.columns)
|
|
702
649
|
name = "acquisition_{0}".format(acquisition_id)
|
|
703
650
|
frame_results['name'] = name
|
|
704
|
-
cell_result_dframe['name'] = name
|
|
705
651
|
frame_results = frame_results.loc[:,['name'] + result_col]
|
|
706
|
-
|
|
707
|
-
|
|
652
|
+
if user_parameters['segmentation_done'] :
|
|
653
|
+
cell_result_dframe['name'] = name
|
|
654
|
+
cell_result_dframe = cell_result_dframe.loc[:,['name'] + cell_result_col]
|
|
655
|
+
cell_result_dframe['total_rna_number'] = cell_result_dframe['nb_rna_in_nuc'] + cell_result_dframe['nb_rna_out_nuc']
|
|
708
656
|
|
|
709
657
|
return frame_results, cell_result_dframe
|
|
710
658
|
|
|
@@ -741,8 +689,8 @@ def _compute_cluster_dataframe(clusters) :
|
|
|
741
689
|
return df
|
|
742
690
|
|
|
743
691
|
def get_nucleus_signal(image, other_images, user_parameters) :
|
|
744
|
-
if user_parameters['
|
|
745
|
-
rna_signal_channel = user_parameters['
|
|
692
|
+
if user_parameters['is_multichannel'] :
|
|
693
|
+
rna_signal_channel = user_parameters['channel_to_compute']
|
|
746
694
|
nucleus_signal_channel = user_parameters['nucleus channel signal']
|
|
747
695
|
if type(nucleus_signal_channel) == type(None) :
|
|
748
696
|
return np.zeros(shape=image.shape)
|
small_fish_gui/pipeline/main.py
CHANGED
|
@@ -5,49 +5,31 @@ This script is called when software starts; it is the main loop.
|
|
|
5
5
|
import pandas as pd
|
|
6
6
|
import PySimpleGUI as sg
|
|
7
7
|
from ..gui import hub_prompt
|
|
8
|
-
from .actions import add_detection, save_results, compute_colocalisation, delete_acquisitions, rename_acquisitions
|
|
8
|
+
from .actions import add_detection, save_results, compute_colocalisation, delete_acquisitions, rename_acquisitions, save_segmentation, load_segmentation, segment_cells
|
|
9
9
|
from ._preprocess import clean_unused_parameters_cache
|
|
10
10
|
from ..batch import batch_promp
|
|
11
|
+
from ..hints import pipeline_parameters
|
|
11
12
|
|
|
12
13
|
#'Global' parameters
|
|
13
|
-
user_parameters =
|
|
14
|
+
user_parameters = pipeline_parameters({'segmentation_done' : False}) #TypedDict
|
|
14
15
|
acquisition_id = -1
|
|
15
|
-
result_df = pd.DataFrame()
|
|
16
|
-
cell_result_df = pd.DataFrame()
|
|
16
|
+
result_df = pd.DataFrame(columns=['acquisition_id'])
|
|
17
|
+
cell_result_df = pd.DataFrame(columns=['acquisition_id'])
|
|
17
18
|
global_coloc_df = pd.DataFrame()
|
|
18
19
|
cell_coloc_df = pd.DataFrame()
|
|
19
|
-
segmentation_done = False
|
|
20
20
|
cytoplasm_label = None
|
|
21
21
|
nucleus_label = None
|
|
22
22
|
|
|
23
|
-
#Use for dev purpose
|
|
24
|
-
MAKE_NEW_SAVE = False
|
|
25
|
-
PATH = "/home/floricslimani/Documents/small_fish_workshop/save"
|
|
26
|
-
LOAD_SAVE = False
|
|
27
|
-
|
|
28
23
|
while True : #Break this loop to close small_fish
|
|
29
24
|
|
|
30
|
-
if LOAD_SAVE :
|
|
31
|
-
result_df = pd.read_csv(PATH + "/result.csv", sep='|')
|
|
32
|
-
cell_result_df = pd.read_csv(PATH + "/cell_result_df.csv", sep='|')
|
|
33
|
-
global_coloc_df = pd.read_csv(PATH + "/global_coloc_df.csv", sep='|')
|
|
34
|
-
cell_coloc_df = pd.read_csv(PATH + "/cell_coloc_df.csv", sep='|')
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
else :
|
|
38
|
-
result_df = result_df.reset_index(drop=True)
|
|
39
|
-
cell_result_df = cell_result_df.reset_index(drop=True)
|
|
40
|
-
global_coloc_df = global_coloc_df.reset_index(drop=True)
|
|
41
|
-
cell_coloc_df = cell_coloc_df.reset_index(drop=True)
|
|
42
25
|
try :
|
|
43
|
-
event, values = hub_prompt(result_df, segmentation_done)
|
|
26
|
+
event, values = hub_prompt(result_df, user_parameters['segmentation_done'])
|
|
44
27
|
|
|
45
28
|
if event == 'Add detection' :
|
|
46
29
|
user_parameters = clean_unused_parameters_cache(user_parameters)
|
|
47
30
|
|
|
48
|
-
new_result_df, new_cell_result_df, acquisition_id, user_parameters
|
|
31
|
+
new_result_df, new_cell_result_df, acquisition_id, user_parameters = add_detection(
|
|
49
32
|
user_parameters=user_parameters,
|
|
50
|
-
segmentation_done=segmentation_done,
|
|
51
33
|
acquisition_id=acquisition_id,
|
|
52
34
|
cytoplasm_label = cytoplasm_label,
|
|
53
35
|
nucleus_label = nucleus_label,
|
|
@@ -55,6 +37,13 @@ while True : #Break this loop to close small_fish
|
|
|
55
37
|
result_df = pd.concat([result_df, new_result_df], axis=0)
|
|
56
38
|
cell_result_df = pd.concat([cell_result_df, new_cell_result_df], axis=0)
|
|
57
39
|
|
|
40
|
+
elif event == 'Segment cells' :
|
|
41
|
+
nucleus_label, cytoplasm_label, user_parameters = segment_cells(
|
|
42
|
+
user_parameters=user_parameters,
|
|
43
|
+
nucleus_label=nucleus_label,
|
|
44
|
+
cytoplasm_label = cytoplasm_label,
|
|
45
|
+
)
|
|
46
|
+
|
|
58
47
|
elif event == 'Save results' :
|
|
59
48
|
save_results(
|
|
60
49
|
result_df=result_df,
|
|
@@ -62,7 +51,16 @@ while True : #Break this loop to close small_fish
|
|
|
62
51
|
global_coloc_df=global_coloc_df,
|
|
63
52
|
cell_coloc_df = cell_coloc_df,
|
|
64
53
|
)
|
|
65
|
-
|
|
54
|
+
|
|
55
|
+
elif event == 'Save segmentation' :
|
|
56
|
+
save_segmentation(
|
|
57
|
+
nucleus_label=nucleus_label,
|
|
58
|
+
cytoplasm_label=cytoplasm_label,
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
elif event == 'Load segmentation' :
|
|
62
|
+
nucleus_label, cytoplasm_label, user_parameters['segmentation_done'] = load_segmentation(nucleus_label, cytoplasm_label, user_parameters['segmentation_done'])
|
|
63
|
+
|
|
66
64
|
elif event == 'Compute colocalisation' :
|
|
67
65
|
result_tables = values.setdefault('result_table', []) #Contains the lines selected by the user on the sum-up array.
|
|
68
66
|
|
|
@@ -74,18 +72,18 @@ while True : #Break this loop to close small_fish
|
|
|
74
72
|
cell_coloc_df=cell_coloc_df,
|
|
75
73
|
)
|
|
76
74
|
|
|
77
|
-
elif event == "Reset
|
|
75
|
+
elif event == "Reset all" :
|
|
78
76
|
result_df = pd.DataFrame()
|
|
79
77
|
cell_result_df = pd.DataFrame()
|
|
80
78
|
global_coloc_df = pd.DataFrame()
|
|
81
79
|
cell_coloc_df = pd.DataFrame()
|
|
82
80
|
acquisition_id = -1
|
|
83
|
-
segmentation_done = False
|
|
81
|
+
user_parameters['segmentation_done'] = False
|
|
84
82
|
cytoplasm_label = None
|
|
85
83
|
nucleus_label = None
|
|
86
84
|
|
|
87
85
|
elif event == "Reset segmentation" :
|
|
88
|
-
segmentation_done = False
|
|
86
|
+
user_parameters['segmentation_done'] = False
|
|
89
87
|
cytoplasm_label = None
|
|
90
88
|
nucleus_label = None
|
|
91
89
|
|
|
@@ -94,7 +92,7 @@ while True : #Break this loop to close small_fish
|
|
|
94
92
|
result_df, cell_result_df, global_coloc_df, cell_coloc_df = delete_acquisitions(selected_acquisitions, result_df, cell_result_df, global_coloc_df, cell_coloc_df)
|
|
95
93
|
|
|
96
94
|
elif event == "Batch detection" :
|
|
97
|
-
result_df, cell_result_df, acquisition_id, user_parameters, segmentation_done, cytoplasm_label,nucleus_label = batch_promp(
|
|
95
|
+
result_df, cell_result_df, acquisition_id, user_parameters, user_parameters['segmentation_done'], cytoplasm_label,nucleus_label = batch_promp(
|
|
98
96
|
result_df,
|
|
99
97
|
cell_result_df,
|
|
100
98
|
acquisition_id=acquisition_id,
|
|
@@ -108,11 +106,6 @@ while True : #Break this loop to close small_fish
|
|
|
108
106
|
else :
|
|
109
107
|
break
|
|
110
108
|
|
|
111
|
-
if MAKE_NEW_SAVE :
|
|
112
|
-
result_df.reset_index(drop=True).to_csv(PATH + "/result.csv", sep='|')
|
|
113
|
-
cell_result_df.reset_index(drop=True).to_csv(PATH + "/cell_result_df.csv", sep='|')
|
|
114
|
-
cell_coloc_df.reset_index(drop=True).to_csv(PATH + "/cell_coloc_df.csv", sep='|')
|
|
115
|
-
global_coloc_df.reset_index(drop=True).to_csv(PATH + "/global_coloc_df.csv", sep='|')
|
|
116
109
|
|
|
117
110
|
except Exception as error :
|
|
118
111
|
sg.popup(str(error))
|