small-fish-gui 1.3.5__py3-none-any.whl → 1.4.0__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/__init__.py +5 -0
- small_fish_gui/batch/input.py +62 -0
- small_fish_gui/batch/integrity.py +158 -0
- small_fish_gui/batch/output.py +0 -0
- small_fish_gui/batch/pipeline.py +218 -0
- small_fish_gui/batch/prompt.py +426 -0
- small_fish_gui/batch/test.py +10 -0
- small_fish_gui/batch/update.py +132 -0
- small_fish_gui/batch/utils.py +66 -0
- small_fish_gui/batch/values.py +3 -0
- small_fish_gui/batch/values.txt +65 -0
- small_fish_gui/gui/animation.py +24 -15
- small_fish_gui/gui/layout.py +7 -4
- small_fish_gui/gui/prompts.py +3 -3
- small_fish_gui/interface/output.py +8 -4
- small_fish_gui/pipeline/__init__.py +21 -0
- small_fish_gui/pipeline/_preprocess.py +62 -8
- small_fish_gui/pipeline/_segmentation.py +36 -0
- small_fish_gui/pipeline/detection.py +68 -7
- small_fish_gui/pipeline/main.py +7 -3
- small_fish_gui/utils.py +6 -1
- {small_fish_gui-1.3.5.dist-info → small_fish_gui-1.4.0.dist-info}/METADATA +1 -1
- {small_fish_gui-1.3.5.dist-info → small_fish_gui-1.4.0.dist-info}/RECORD +26 -16
- small_fish_gui/gui/batch.py +0 -312
- small_fish_gui/gui/test.py +0 -5
- {small_fish_gui-1.3.5.dist-info → small_fish_gui-1.4.0.dist-info}/WHEEL +0 -0
- {small_fish_gui-1.3.5.dist-info → small_fish_gui-1.4.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Submodule with main function to call to launch batch mode.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
import PySimpleGUI as sg
|
|
7
|
+
|
|
8
|
+
from .utils import get_elmt_from_key, create_map, call_auto_map
|
|
9
|
+
from .pipeline import batch_pipeline
|
|
10
|
+
from .update import update_detection_tab, update_map_tab, update_master_parameters, update_segmentation_tab, update_output_tab
|
|
11
|
+
from .input import load, extract_files
|
|
12
|
+
from .integrity import sanity_check, check_channel_map_integrity, check_detection_parameters, check_segmentation_parameters, check_output_parameters
|
|
13
|
+
from ..gui.layout import _segmentation_layout, _detection_layout, _input_parameters_layout, _ask_channel_map_layout
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def batch_promp(
|
|
17
|
+
results_df,
|
|
18
|
+
cell_results_df,
|
|
19
|
+
acquisition_id,
|
|
20
|
+
preset: dict={},
|
|
21
|
+
) :
|
|
22
|
+
|
|
23
|
+
files_values = [[]]
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
#LOAD FILES
|
|
27
|
+
files_table = sg.Table(values=files_values, headings=['Filenames'], col_widths=100, max_col_width= 200, def_col_width=100, num_rows= 10, auto_size_columns=False)
|
|
28
|
+
|
|
29
|
+
#DIMENSION SANITY
|
|
30
|
+
sanity_progress = sg.ProgressBar(10, size_px=(500,10), border_width=2)
|
|
31
|
+
sanity_check_button = sg.Button(
|
|
32
|
+
'Check',
|
|
33
|
+
tooltip= "Will check that all files loaded have the same dimension number and that small fish is able to open them.",
|
|
34
|
+
pad=(10,0))
|
|
35
|
+
sanity_header = sg.Text("Dimension sanity", font=('bold',15), pad=(0,10))
|
|
36
|
+
dimension_number_text = sg.Text("Dimension number : unknown")
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
#########################################
|
|
40
|
+
##### COLUMNS
|
|
41
|
+
#########################################
|
|
42
|
+
|
|
43
|
+
##### Tabs
|
|
44
|
+
|
|
45
|
+
#Input tab
|
|
46
|
+
input_layout = _input_parameters_layout(
|
|
47
|
+
ask_for_segmentation=True,
|
|
48
|
+
is_3D_stack_preset= preset.setdefault("3D stack" ,False),
|
|
49
|
+
time_stack_preset=False,
|
|
50
|
+
multichannel_preset=preset.setdefault("multichannel" ,False),
|
|
51
|
+
do_dense_regions_deconvolution_preset=preset.setdefault("Dense regions deconvolution" ,False),
|
|
52
|
+
do_clustering_preset= preset.setdefault("Cluster computation", False),
|
|
53
|
+
do_Napari_correction=False,
|
|
54
|
+
do_segmentation_preset= preset.setdefault("Segmentation", False),
|
|
55
|
+
)
|
|
56
|
+
input_layout += [[sg.Button('Ok')]]
|
|
57
|
+
input_tab = sg.Tab("Input", input_layout)
|
|
58
|
+
|
|
59
|
+
napari_correction_elmt = get_elmt_from_key(input_tab, key='Napari correction')
|
|
60
|
+
|
|
61
|
+
#Maptab
|
|
62
|
+
map_layout = _ask_channel_map_layout(
|
|
63
|
+
shape=(0,1,2,3,4),
|
|
64
|
+
is_3D_stack=True,
|
|
65
|
+
is_time_stack=True,
|
|
66
|
+
multichannel=True,
|
|
67
|
+
)
|
|
68
|
+
last_shape_read = sg.Text("Last shape read : None")
|
|
69
|
+
auto_map = sg.Button("auto-map", disabled=True, pad=(10,0))
|
|
70
|
+
apply_map_button = sg.Button("apply", disabled=True, pad=(10,0), key='apply-map')
|
|
71
|
+
map_layout += [[last_shape_read]]
|
|
72
|
+
map_layout += [[auto_map, apply_map_button]]
|
|
73
|
+
map_tab = sg.Tab("Map", map_layout)
|
|
74
|
+
|
|
75
|
+
#Segmentation tab
|
|
76
|
+
segmentation_layout = _segmentation_layout(
|
|
77
|
+
multichannel=True,
|
|
78
|
+
cytoplasm_model_preset=preset.setdefault("cyto_model_name",'cyto3'),
|
|
79
|
+
cytoplasm_channel_preset=preset.setdefault("cytoplasm channel",0),
|
|
80
|
+
cyto_diameter_preset=preset.setdefault("cytoplasm diameter",180),
|
|
81
|
+
nucleus_model_preset=preset.setdefault("nucleus_model_name",'nuclei'),
|
|
82
|
+
nucleus_channel_preset=preset.setdefault("nucleus channel",0),
|
|
83
|
+
nucleus_diameter_preset=preset.setdefault("nucleus diameter",150),
|
|
84
|
+
segment_only_nuclei_preset=preset.setdefault("Segment only nuclei",False)
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
apply_segmentation_button = sg.Button('apply', key='apply-segmentation')
|
|
88
|
+
segmentation_layout += [[apply_segmentation_button]]
|
|
89
|
+
seg_keys_to_hide = ['show segmentation', 'saving path', 'filename']
|
|
90
|
+
segmentation_tab = sg.Tab("Segmentation", segmentation_layout, visible=False)
|
|
91
|
+
|
|
92
|
+
#Detection tab
|
|
93
|
+
detection_layout = _detection_layout(
|
|
94
|
+
is_3D_stack=True,
|
|
95
|
+
is_multichannel=True,
|
|
96
|
+
do_clustering=True,
|
|
97
|
+
do_dense_region_deconvolution=True,
|
|
98
|
+
do_segmentation=True,
|
|
99
|
+
default_dict= preset,
|
|
100
|
+
)
|
|
101
|
+
apply_detection_button = sg.Button('apply', key='apply-detection')
|
|
102
|
+
detection_layout += [[apply_detection_button]]
|
|
103
|
+
detection_keys_to_hide = ['do_spots_csv', 'do_spots_excel', 'do_spots_feather','spots_filename','spots_extraction_folder']
|
|
104
|
+
detection_tab = sg.Tab("Detection", detection_layout, visible=False)
|
|
105
|
+
|
|
106
|
+
#Output tab
|
|
107
|
+
show_batch_folder_text = sg.Text('', key= 'batch_folder_text')
|
|
108
|
+
apply_output_button = sg.Button('apply', key='apply-output')
|
|
109
|
+
save_segmentation_box = sg.Checkbox("save segmentation", disabled=True, key='save segmentation')
|
|
110
|
+
save_detection_box = sg.Checkbox("create spot detection visuals", key= 'save detection', tooltip="Create multichannel tiff with raw spot signal and detected spots.\nWarning if processing a lot of files make sure you have enough free space on your hard drive.")
|
|
111
|
+
extract_spots_box = sg.Checkbox("extract spots", key='extract spots')
|
|
112
|
+
batch_name_input = sg.InputText(size=25, key='batch_name')
|
|
113
|
+
output_layout=[
|
|
114
|
+
[sg.Text("Output folder", font=('bold',15), pad=(0,10))],
|
|
115
|
+
[show_batch_folder_text],
|
|
116
|
+
[sg.Text("Select a folder : "), sg.FolderBrowse(initial_folder=os.getcwd(), key='output_folder', target=(1,-1))],
|
|
117
|
+
[sg.Text("Name for batch : "), batch_name_input],
|
|
118
|
+
[save_segmentation_box],
|
|
119
|
+
[save_detection_box],
|
|
120
|
+
[extract_spots_box],
|
|
121
|
+
[sg.Text("Data extension", font=('bold',15), pad=(0,10))],
|
|
122
|
+
[sg.Checkbox(".csv", key='csv'),sg.Checkbox(".xlsx", key='xlsx'),sg.Checkbox(".feather", key='feather'),],
|
|
123
|
+
[apply_output_button],
|
|
124
|
+
]
|
|
125
|
+
output_tab = sg.Tab("Output", output_layout, visible=True)
|
|
126
|
+
|
|
127
|
+
##TAB GROUP
|
|
128
|
+
_tab_group = sg.TabGroup([[input_tab, map_tab, segmentation_tab, detection_tab, output_tab]], enable_events=True)
|
|
129
|
+
tab_col = sg.Column( #Allow the tab to be scrollable
|
|
130
|
+
[[_tab_group]],
|
|
131
|
+
scrollable=True,
|
|
132
|
+
vertical_scroll_only=True,
|
|
133
|
+
s= (390,390),
|
|
134
|
+
pad=((0,0),(5,5))
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
tab_dict= {
|
|
138
|
+
"Input" : input_tab,
|
|
139
|
+
"Segmentation" : segmentation_tab,
|
|
140
|
+
"Detection" : detection_tab,
|
|
141
|
+
"Map" : map_tab,
|
|
142
|
+
"Output" : output_tab
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
##### Launcher
|
|
146
|
+
|
|
147
|
+
start_button =sg.Button('Start', button_color= 'green', disabled= True, pad= ((115,5),(0,10)))
|
|
148
|
+
stop_button = sg.Button('Cancel', button_color= 'red', pad= ((5,115),(0,10)))
|
|
149
|
+
batch_progression_bar = sg.ProgressBar(max_value=0, size_px=(340,20), bar_color= ('blue','black'), border_width=2, pad=((15,0),(30,0)))
|
|
150
|
+
mapping_ok_text = sg.Text('Uncorrect mapping', text_color='gray', font='roman 14 bold', pad=((0,0),(100,5)))
|
|
151
|
+
segmentation_ok_text = sg.Text('Uncorrect segmentation settings', font='roman 14 bold', pad=(0,5), text_color='gray', visible=False)
|
|
152
|
+
detection_ok_text = sg.Text('Uncorrect detection settings', text_color='gray', font='roman 14 bold', pad=(0,5))
|
|
153
|
+
output_ok_text = sg.Text('Uncorrect output parameters', text_color='gray', font='roman 14 bold', pad=(0,5))
|
|
154
|
+
current_acquisition_text = sg.Text('0', text_color='gray', font='roman 15 bold', pad= ((150,5),(10,10)))
|
|
155
|
+
total_acquisition_text = sg.Text('/ 0', text_color='gray', font='roman 15 bold', pad= ((5,150),(10,10)))
|
|
156
|
+
|
|
157
|
+
launcher_layout = [
|
|
158
|
+
[mapping_ok_text],
|
|
159
|
+
[segmentation_ok_text],
|
|
160
|
+
[detection_ok_text],
|
|
161
|
+
[output_ok_text],
|
|
162
|
+
[batch_progression_bar],
|
|
163
|
+
[current_acquisition_text,total_acquisition_text],
|
|
164
|
+
[start_button, stop_button],
|
|
165
|
+
]
|
|
166
|
+
launch_col = sg.Column( #Allow the tab to be scrollable
|
|
167
|
+
launcher_layout,
|
|
168
|
+
s= (390,390),
|
|
169
|
+
pad=((3,5),(5,5))
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
#########################################
|
|
173
|
+
##### Window Creation
|
|
174
|
+
#########################################
|
|
175
|
+
stream_output = sg.Output(size=(100,10), pad=(30,10), visible=True)
|
|
176
|
+
layout = [
|
|
177
|
+
[sg.Text("Batch Processing", font=('bold',20), pad=((300,0),(0,2)))],
|
|
178
|
+
[sg.Text("Select a folder : "), sg.FolderBrowse(initial_folder=os.getcwd(), key='Batch_folder'), sg.Button('Load')],
|
|
179
|
+
[files_table],
|
|
180
|
+
[sanity_header, sanity_check_button, sanity_progress],
|
|
181
|
+
[dimension_number_text],
|
|
182
|
+
[tab_col, launch_col],
|
|
183
|
+
[stream_output],
|
|
184
|
+
]
|
|
185
|
+
stream_output.restore_stderr()
|
|
186
|
+
stream_output.restore_stdout()
|
|
187
|
+
|
|
188
|
+
window = sg.Window("small fish", layout=layout, size= (800,800), auto_size_buttons=True, auto_size_text=True, resizable=True)
|
|
189
|
+
|
|
190
|
+
#MASTER PARAMETERS
|
|
191
|
+
Master_parameters_dict ={
|
|
192
|
+
'_map' : {},
|
|
193
|
+
'_is_mapping_correct' : False,
|
|
194
|
+
'_is_segmentation_correct' : None, # None : segmentation disabled; Then true/false if enabled
|
|
195
|
+
'_is_detection_correct' : False,
|
|
196
|
+
'_is_output_correct' : False,
|
|
197
|
+
}
|
|
198
|
+
Master_parameters_update_dict = {
|
|
199
|
+
'_is_mapping_correct' : mapping_ok_text,
|
|
200
|
+
'_is_segmentation_correct' : segmentation_ok_text, # None : segmentation disabled; Then true/false if enabled
|
|
201
|
+
'_is_detection_correct' : detection_ok_text,
|
|
202
|
+
'_is_output_correct' : output_ok_text,
|
|
203
|
+
|
|
204
|
+
}
|
|
205
|
+
loop = 0
|
|
206
|
+
timeout = 1
|
|
207
|
+
last_shape = None
|
|
208
|
+
talk=True
|
|
209
|
+
|
|
210
|
+
#########################################
|
|
211
|
+
##### Event Loop : break to close window
|
|
212
|
+
#########################################
|
|
213
|
+
|
|
214
|
+
#Hiding options for non batch mode
|
|
215
|
+
window= window.finalize()
|
|
216
|
+
napari_correction_elmt.update(disabled=True)
|
|
217
|
+
get_elmt_from_key(tab_dict['Input'], key= 'image path').update(disabled=True)
|
|
218
|
+
for key in seg_keys_to_hide : get_elmt_from_key(tab_dict['Segmentation'], key=key).update(disabled=True)
|
|
219
|
+
for key in detection_keys_to_hide : get_elmt_from_key(tab_dict['Detection'], key=key).update(disabled=True)
|
|
220
|
+
|
|
221
|
+
while True :
|
|
222
|
+
try :
|
|
223
|
+
loop +=1
|
|
224
|
+
window = window.refresh()
|
|
225
|
+
event, values = window.read(timeout=timeout)
|
|
226
|
+
|
|
227
|
+
#Welcome message
|
|
228
|
+
if loop == 1 :
|
|
229
|
+
timeout = 500
|
|
230
|
+
print("Welcome to small fish batch analysis. Please start by loading some files and setting parameters.")
|
|
231
|
+
|
|
232
|
+
batch_folder = values.get('Batch_folder')
|
|
233
|
+
is_multichanel = values.get('multichannel')
|
|
234
|
+
is_3D = values.get('3D stack')
|
|
235
|
+
do_segmentation = values.get('Segmentation')
|
|
236
|
+
do_dense_regions_deconvolution = values.get('Dense regions deconvolution')
|
|
237
|
+
do_clustering = values.get('Cluster computation')
|
|
238
|
+
|
|
239
|
+
if type(batch_folder) != type(None) and event == 'Load':
|
|
240
|
+
|
|
241
|
+
files_values, last_shape, dim_number = load(batch_folder)
|
|
242
|
+
files_table.update(values=files_values)
|
|
243
|
+
last_shape_read.update("Last shape read : {0}".format(last_shape))
|
|
244
|
+
dimension_number_text.update("Dimension number : {0}".format(dim_number))
|
|
245
|
+
update_map_tab(
|
|
246
|
+
tab_elmt=tab_dict.get("Map"),
|
|
247
|
+
is_3D=is_3D,
|
|
248
|
+
is_multichannel=is_multichanel,
|
|
249
|
+
last_shape=last_shape
|
|
250
|
+
)
|
|
251
|
+
filename_list = extract_files(files_values)
|
|
252
|
+
|
|
253
|
+
elif event == 'Check' :
|
|
254
|
+
last_shape = sanity_check(
|
|
255
|
+
filename_list=filename_list,
|
|
256
|
+
batch_folder=batch_folder,
|
|
257
|
+
window=window,
|
|
258
|
+
progress_bar=sanity_progress
|
|
259
|
+
)
|
|
260
|
+
if isinstance(last_shape,(tuple,list)) :
|
|
261
|
+
dim_number = len(last_shape)
|
|
262
|
+
dimension_number_text.update("Dimension number : {0}".format(dim_number))
|
|
263
|
+
auto_map.update(disabled=False)
|
|
264
|
+
else :
|
|
265
|
+
dim_number = None
|
|
266
|
+
dimension_number_text.update("Dimension number : unknown")
|
|
267
|
+
auto_map.update(disabled=True)
|
|
268
|
+
|
|
269
|
+
last_shape_read.update("Last shape read : {0}".format(last_shape))
|
|
270
|
+
|
|
271
|
+
elif event == _tab_group.key or event == 'Ok': #Tab switch in parameters
|
|
272
|
+
|
|
273
|
+
update_map_tab(
|
|
274
|
+
tab_elmt=tab_dict.get("Map"),
|
|
275
|
+
is_3D=is_3D,
|
|
276
|
+
is_multichannel=is_multichanel,
|
|
277
|
+
last_shape=last_shape
|
|
278
|
+
)
|
|
279
|
+
|
|
280
|
+
elif event == 'auto-map' :
|
|
281
|
+
Master_parameters_dict['_map'] = call_auto_map(
|
|
282
|
+
tab_elmt=tab_dict.get("Map"),
|
|
283
|
+
shape=last_shape,
|
|
284
|
+
is_3D=is_3D,
|
|
285
|
+
is_multichannel=is_multichanel
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
Master_parameters_dict['_is_mapping_correct'] = check_channel_map_integrity(
|
|
289
|
+
maping=Master_parameters_dict['_map'],
|
|
290
|
+
shape=last_shape,
|
|
291
|
+
expected_dim=dim_number
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
if not Master_parameters_dict['_is_mapping_correct'] : Master_parameters_dict['_map'] = {}
|
|
295
|
+
|
|
296
|
+
elif event == 'apply-map' :
|
|
297
|
+
|
|
298
|
+
Master_parameters_dict['_map'] = create_map(
|
|
299
|
+
values=values,
|
|
300
|
+
is_3D=is_3D,
|
|
301
|
+
is_multichannel=is_multichanel,
|
|
302
|
+
)
|
|
303
|
+
|
|
304
|
+
Master_parameters_dict['_is_mapping_correct'] = check_channel_map_integrity(
|
|
305
|
+
maping=Master_parameters_dict['_map'],
|
|
306
|
+
shape=last_shape,
|
|
307
|
+
expected_dim=dim_number
|
|
308
|
+
)
|
|
309
|
+
|
|
310
|
+
if not Master_parameters_dict['_is_mapping_correct'] : Master_parameters_dict['_map'] = {}
|
|
311
|
+
|
|
312
|
+
elif event == 'apply-segmentation' :
|
|
313
|
+
Master_parameters_dict['_is_segmentation_correct'], values = check_segmentation_parameters(
|
|
314
|
+
values=values,
|
|
315
|
+
shape=last_shape,
|
|
316
|
+
is_multichannel=is_multichanel
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
elif event == 'apply-detection' :
|
|
320
|
+
Master_parameters_dict['_is_detection_correct'], values = check_detection_parameters(
|
|
321
|
+
values=values,
|
|
322
|
+
do_dense_region_deconvolution=do_dense_regions_deconvolution,
|
|
323
|
+
do_clustering=do_clustering,
|
|
324
|
+
is_multichannel=is_multichanel,
|
|
325
|
+
is_3D=is_3D,
|
|
326
|
+
map= Master_parameters_dict.get('_map'),
|
|
327
|
+
shape=last_shape
|
|
328
|
+
)
|
|
329
|
+
|
|
330
|
+
elif event == 'apply-output' :
|
|
331
|
+
Master_parameters_dict['_is_output_correct'], values = check_output_parameters(values)
|
|
332
|
+
batch_name_input.update(value=values.get('batch_name'))
|
|
333
|
+
|
|
334
|
+
elif event == "Cancel" :
|
|
335
|
+
raise InterruptedError("cancel")
|
|
336
|
+
|
|
337
|
+
elif event == None :
|
|
338
|
+
raise InterruptedError("closed")
|
|
339
|
+
elif event == sg.WINDOW_CLOSED :
|
|
340
|
+
raise InterruptedError("closed")
|
|
341
|
+
|
|
342
|
+
elif event == 'Start' :
|
|
343
|
+
start_button.update(disabled=True)
|
|
344
|
+
results_df, cell_results_df, acquisition_id = batch_pipeline(
|
|
345
|
+
batch_window= window,
|
|
346
|
+
batch_progress_bar= batch_progression_bar,
|
|
347
|
+
progress_count=current_acquisition_text,
|
|
348
|
+
parameters=values,
|
|
349
|
+
filenames_list=filename_list,
|
|
350
|
+
do_segmentation=do_segmentation,
|
|
351
|
+
map= Master_parameters_dict['_map'],
|
|
352
|
+
results_df=results_df,
|
|
353
|
+
cell_results_df=cell_results_df,
|
|
354
|
+
is_3D=is_3D,
|
|
355
|
+
last_acquisition_id=acquisition_id+1,
|
|
356
|
+
)
|
|
357
|
+
stream_output.restore_stderr()
|
|
358
|
+
stream_output.restore_stdout()
|
|
359
|
+
|
|
360
|
+
window.close()
|
|
361
|
+
return results_df, cell_results_df, acquisition_id, values, False, None,None #Segmentation done : False, cell label : None, Nucleus label : None
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
#End of loop
|
|
365
|
+
|
|
366
|
+
#If user loads other files
|
|
367
|
+
if type(last_shape) != type(None) :
|
|
368
|
+
if len(last_shape) != 2 + is_3D + is_multichanel :
|
|
369
|
+
Master_parameters_dict['_is_mapping_correct'] = False
|
|
370
|
+
Master_parameters_dict['_is_detection_correct'] = False
|
|
371
|
+
Master_parameters_dict['_is_segmentation_correct'] = False
|
|
372
|
+
else :
|
|
373
|
+
Master_parameters_dict['_is_mapping_correct'] = False
|
|
374
|
+
Master_parameters_dict['_is_detection_correct'] = False
|
|
375
|
+
Master_parameters_dict['_is_segmentation_correct'] = False
|
|
376
|
+
|
|
377
|
+
update_master_parameters(
|
|
378
|
+
Master_parameter_dict=Master_parameters_dict,
|
|
379
|
+
update_dict=Master_parameters_update_dict
|
|
380
|
+
)
|
|
381
|
+
|
|
382
|
+
update_segmentation_tab(
|
|
383
|
+
tab_elmt=tab_dict.get("Segmentation"),
|
|
384
|
+
segmentation_correct_text= segmentation_ok_text,
|
|
385
|
+
do_segmentation=do_segmentation,
|
|
386
|
+
is_multichannel=is_multichanel,
|
|
387
|
+
is_mapping_ok=Master_parameters_dict['_is_mapping_correct']
|
|
388
|
+
)
|
|
389
|
+
|
|
390
|
+
update_detection_tab(
|
|
391
|
+
tab_elmt=tab_dict.get("Detection"),
|
|
392
|
+
is_multichannel=is_multichanel,
|
|
393
|
+
is_3D=is_3D,
|
|
394
|
+
do_dense_region_deconvolution=do_dense_regions_deconvolution,
|
|
395
|
+
do_clustering=do_clustering,
|
|
396
|
+
is_mapping_ok=Master_parameters_dict['_is_mapping_correct'],
|
|
397
|
+
do_segmentation=do_segmentation,
|
|
398
|
+
)
|
|
399
|
+
|
|
400
|
+
update_output_tab(
|
|
401
|
+
tab_elmt=tab_dict['Output'],
|
|
402
|
+
do_segmentation=do_segmentation,
|
|
403
|
+
output_folder=values['output_folder'],
|
|
404
|
+
)
|
|
405
|
+
|
|
406
|
+
_segmentation_ready = (Master_parameters_dict['_is_segmentation_correct'] and do_segmentation) or not do_segmentation
|
|
407
|
+
if Master_parameters_dict['_is_detection_correct'] and Master_parameters_dict['_is_output_correct'] and Master_parameters_dict['_is_mapping_correct'] and _segmentation_ready :
|
|
408
|
+
start_button.update(button_color='blue', disabled=False)
|
|
409
|
+
total_acquisition_text.update("/ {0}".format(len(filename_list)))
|
|
410
|
+
batch_progression_bar.update(current_count=0, bar_color=('green','blue'))
|
|
411
|
+
if talk :
|
|
412
|
+
print("Small fish is ready, launch with the start button.")
|
|
413
|
+
talk= False
|
|
414
|
+
else :
|
|
415
|
+
talk = True
|
|
416
|
+
start_button.update(button_color='green', disabled=True)
|
|
417
|
+
total_acquisition_text.update("/ 0")
|
|
418
|
+
batch_progression_bar.update(current_count=0, bar_color=('blue','black'))
|
|
419
|
+
|
|
420
|
+
except Exception as e :
|
|
421
|
+
stream_output.restore_stderr()
|
|
422
|
+
stream_output.restore_stdout()
|
|
423
|
+
raise e
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
window.close()
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Functions handling GUI update while user is interacting with software.
|
|
3
|
+
"""
|
|
4
|
+
import PySimpleGUI as sg
|
|
5
|
+
|
|
6
|
+
from .utils import get_elmt_from_key
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def update_master_parameters(
|
|
11
|
+
Master_parameter_dict:dict,
|
|
12
|
+
update_dict:dict
|
|
13
|
+
) :
|
|
14
|
+
for parameter, is_ok in Master_parameter_dict.items() :
|
|
15
|
+
elmt_to_update:sg.Element = update_dict.get(parameter)
|
|
16
|
+
if type(elmt_to_update) == type(None): continue
|
|
17
|
+
else :
|
|
18
|
+
if is_ok :
|
|
19
|
+
text:str = elmt_to_update.DisplayText.replace('Uncorrect', 'Correct')
|
|
20
|
+
color = 'green'
|
|
21
|
+
else :
|
|
22
|
+
text:str = elmt_to_update.DisplayText.replace('Correct', 'Uncorrect')
|
|
23
|
+
color = 'gray'
|
|
24
|
+
|
|
25
|
+
elmt_to_update.update(value=text, text_color = color)
|
|
26
|
+
|
|
27
|
+
def update_detection_tab(
|
|
28
|
+
tab_elmt:sg.Tab,
|
|
29
|
+
is_multichannel,
|
|
30
|
+
is_3D,
|
|
31
|
+
do_dense_region_deconvolution,
|
|
32
|
+
do_clustering,
|
|
33
|
+
is_mapping_ok,
|
|
34
|
+
do_segmentation,
|
|
35
|
+
) :
|
|
36
|
+
|
|
37
|
+
#Acess elements
|
|
38
|
+
##Detection
|
|
39
|
+
channel_to_compute = get_elmt_from_key(tab_elmt, key= 'channel to compute')
|
|
40
|
+
voxel_size_z = get_elmt_from_key(tab_elmt, key= 'voxel_size_z')
|
|
41
|
+
spot_size_z = get_elmt_from_key(tab_elmt, key= 'spot_size_z')
|
|
42
|
+
log_kernel_size_z = get_elmt_from_key(tab_elmt, key= 'log_kernel_size_z')
|
|
43
|
+
minimum_distance_z = get_elmt_from_key(tab_elmt, key= 'minimum_distance_z')
|
|
44
|
+
|
|
45
|
+
##Dense regions deconvolution
|
|
46
|
+
alpha = get_elmt_from_key(tab_elmt, key= 'alpha')
|
|
47
|
+
beta = get_elmt_from_key(tab_elmt, key= 'beta')
|
|
48
|
+
gamma = get_elmt_from_key(tab_elmt, key= 'gamma')
|
|
49
|
+
deconvolution_kernel_x = get_elmt_from_key(tab_elmt, key= 'deconvolution_kernel_x')
|
|
50
|
+
deconvolution_kernel_y = get_elmt_from_key(tab_elmt, key= 'deconvolution_kernel_y')
|
|
51
|
+
deconvolution_kernel_z = get_elmt_from_key(tab_elmt, key= 'deconvolution_kernel_z')
|
|
52
|
+
|
|
53
|
+
#Clustering
|
|
54
|
+
cluster_size = get_elmt_from_key(tab_elmt, key= 'cluster size')
|
|
55
|
+
min_number_of_spot = get_elmt_from_key(tab_elmt, key= 'min number of spots')
|
|
56
|
+
|
|
57
|
+
#segmentation and multichannel
|
|
58
|
+
nucleus_channel_signal = get_elmt_from_key(tab_elmt, key= 'nucleus channel signal')
|
|
59
|
+
|
|
60
|
+
#disable
|
|
61
|
+
interactive_threshold_selector = get_elmt_from_key(tab_elmt, key= 'Interactive threshold selector')
|
|
62
|
+
|
|
63
|
+
update_dict={
|
|
64
|
+
'is_3D' : is_3D,
|
|
65
|
+
'is_multichannel' : is_multichannel,
|
|
66
|
+
'do_dense_region_deconvolution' : do_dense_region_deconvolution,
|
|
67
|
+
'do_clustering' : do_clustering,
|
|
68
|
+
'always_hidden' : False,
|
|
69
|
+
'is_3D&do_denseregion' : is_3D and do_dense_region_deconvolution,
|
|
70
|
+
'do_segmentation' : do_segmentation and is_multichannel
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
list_dict={
|
|
74
|
+
'is_3D' : [voxel_size_z, spot_size_z, log_kernel_size_z, minimum_distance_z, ],
|
|
75
|
+
'is_multichannel' : [channel_to_compute],
|
|
76
|
+
'do_dense_region_deconvolution' : [alpha,beta,gamma, deconvolution_kernel_x, deconvolution_kernel_y],
|
|
77
|
+
'do_clustering' : [cluster_size, min_number_of_spot],
|
|
78
|
+
'always_hidden' : [interactive_threshold_selector, ],
|
|
79
|
+
'is_3D&do_denseregion' : [deconvolution_kernel_z],
|
|
80
|
+
'do_segmentation' : [nucleus_channel_signal]
|
|
81
|
+
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
for key, enabled in update_dict.items() :
|
|
85
|
+
for elmt in list_dict.get(key) :
|
|
86
|
+
elmt.update(disabled=not enabled)
|
|
87
|
+
|
|
88
|
+
tab_elmt.update(visible=is_mapping_ok)
|
|
89
|
+
|
|
90
|
+
def update_segmentation_tab(tab_elmt : sg.Tab, segmentation_correct_text : sg.Text, do_segmentation, is_multichannel, is_mapping_ok) :
|
|
91
|
+
|
|
92
|
+
#Access elements
|
|
93
|
+
cytoplasm_channel_elmt = get_elmt_from_key(tab_elmt, key= 'cytoplasm channel')
|
|
94
|
+
nucleus_channel_elmt = get_elmt_from_key(tab_elmt, key= 'nucleus channel')
|
|
95
|
+
|
|
96
|
+
#Update values
|
|
97
|
+
cytoplasm_channel_elmt.update(disabled = not is_multichannel)
|
|
98
|
+
nucleus_channel_elmt.update(disabled = not is_multichannel)
|
|
99
|
+
segmentation_correct_text.update(visible= do_segmentation)
|
|
100
|
+
|
|
101
|
+
tab_elmt.update(visible=is_mapping_ok and do_segmentation)
|
|
102
|
+
|
|
103
|
+
def update_map_tab(
|
|
104
|
+
tab_elmt : sg.Tab,
|
|
105
|
+
is_3D,
|
|
106
|
+
is_multichannel,
|
|
107
|
+
last_shape,
|
|
108
|
+
|
|
109
|
+
) :
|
|
110
|
+
#Acess elments
|
|
111
|
+
t_element = get_elmt_from_key(tab_elmt, key= 't')
|
|
112
|
+
c_element = get_elmt_from_key(tab_elmt, key= 'c')
|
|
113
|
+
z_element = get_elmt_from_key(tab_elmt, key= 'z')
|
|
114
|
+
automap_element = get_elmt_from_key(tab_elmt, key= 'auto-map')
|
|
115
|
+
apply_element = get_elmt_from_key(tab_elmt, key= 'apply-map')
|
|
116
|
+
|
|
117
|
+
#Update values
|
|
118
|
+
t_element.update(disabled=True)
|
|
119
|
+
c_element.update(disabled=not is_multichannel)
|
|
120
|
+
z_element.update(disabled=not is_3D)
|
|
121
|
+
automap_element.update(disabled=type(last_shape) == type(None))
|
|
122
|
+
apply_element.update(disabled=type(last_shape) == type(None))
|
|
123
|
+
|
|
124
|
+
def update_output_tab(
|
|
125
|
+
tab_elmt : sg.Tab,
|
|
126
|
+
do_segmentation,
|
|
127
|
+
output_folder,
|
|
128
|
+
) :
|
|
129
|
+
segmentation_box = get_elmt_from_key(tab_elmt, "save segmentation")
|
|
130
|
+
segmentation_box.update(disabled = not do_segmentation)
|
|
131
|
+
batch_folder_text = get_elmt_from_key(tab_elmt, "batch_folder_text")
|
|
132
|
+
batch_folder_text.update(value = output_folder)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import PySimpleGUI as sg
|
|
2
|
+
from ..pipeline._preprocess import _auto_map_channels
|
|
3
|
+
from ..pipeline._preprocess import MappingError
|
|
4
|
+
|
|
5
|
+
def get_elmt_from_key(Tab_elmt:sg.Tab, key) -> sg.Element:
|
|
6
|
+
elmt_list = sum(Tab_elmt.Rows,[])
|
|
7
|
+
for elmt in elmt_list :
|
|
8
|
+
if elmt.Key == key : return elmt
|
|
9
|
+
raise KeyError("{0} key not found amongst {1}.".format(key, [elmt.Key for elmt in elmt_list]))
|
|
10
|
+
|
|
11
|
+
def call_auto_map(
|
|
12
|
+
tab_elmt: sg.Tab,
|
|
13
|
+
shape,
|
|
14
|
+
is_3D,
|
|
15
|
+
is_multichannel,
|
|
16
|
+
) :
|
|
17
|
+
|
|
18
|
+
if len(shape) < 2 + is_3D + is_multichannel :
|
|
19
|
+
sg.popup("Image is of dimension {0} and you're trying to map {1} dimensions".format(len(shape), 2+is_3D+is_multichannel))
|
|
20
|
+
return {}
|
|
21
|
+
|
|
22
|
+
#Get auto map
|
|
23
|
+
try :
|
|
24
|
+
map = _auto_map_channels(
|
|
25
|
+
is_3D_stack=is_3D,
|
|
26
|
+
is_time_stack=False,
|
|
27
|
+
multichannel=is_multichannel,
|
|
28
|
+
image=None,
|
|
29
|
+
shape=shape
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
except MappingError as e :
|
|
33
|
+
sg.popup_error(e)
|
|
34
|
+
return {}
|
|
35
|
+
|
|
36
|
+
else :
|
|
37
|
+
#Acess elemnt
|
|
38
|
+
x_elmt = get_elmt_from_key(tab_elmt, 'x')
|
|
39
|
+
y_elmt = get_elmt_from_key(tab_elmt, 'y')
|
|
40
|
+
z_elmt = get_elmt_from_key(tab_elmt, 'z')
|
|
41
|
+
c_elmt = get_elmt_from_key(tab_elmt, 'c')
|
|
42
|
+
|
|
43
|
+
#Update values
|
|
44
|
+
x_elmt.update(value=map.get('x'))
|
|
45
|
+
y_elmt.update(value=map.get('y'))
|
|
46
|
+
z_elmt.update(value=map.get('z'))
|
|
47
|
+
c_elmt.update(value=map.get('c'))
|
|
48
|
+
|
|
49
|
+
return map
|
|
50
|
+
|
|
51
|
+
def create_map(
|
|
52
|
+
values:dict,
|
|
53
|
+
is_3D:bool,
|
|
54
|
+
is_multichannel:bool
|
|
55
|
+
) :
|
|
56
|
+
|
|
57
|
+
maping ={
|
|
58
|
+
'x': values.get('x'),
|
|
59
|
+
'y': values.get('y')
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if is_3D : maping['z'] = values.get('z')
|
|
63
|
+
if is_multichannel : maping['c'] = values.get('c')
|
|
64
|
+
|
|
65
|
+
return maping
|
|
66
|
+
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
a = {'Batch_folder': '', 0: [], 'image path': '', '3D stack': False, 'multichannel': False, 'Dense regions deconvolution': False, 'Cluster computation': False, 'Segmentation': False, 'Napari correction': False, 'x': '0', 'y': '0', 'z': '0', 'c': '0', 't': '0', 'cyto_model_name': 'cyto3', 'cytoplasm channel': '0', 'cytoplasm diameter': '30', 'nucleus_model_name': 'nuclei', 'nucleus channel': '0', 'nucleus diameter': '30', 'Segment only nuclei': False, 'show segmentation': False, 'saving path': '', 'filename': 'cell_segmentation.png', 'threshold': '', 'threshold penalty': '1', 'channel to compute': '', 'voxel_size_z': 'z', 'voxel_size_y': 'y', 'voxel_size_x': 'x', 'spot_size_z': 'z', 'spot_size_y': 'y', 'spot_size_x': 'x', 'log_kernel_size_z': 'z', 'log_kernel_size_y': 'y', 'log_kernel_size_x': 'x', 'minimum_distance_z': 'z', 'minimum_distance_y': 'y', 'minimum_distance_x': 'x', 'nucleus channel signal': '(0,)', 'alpha': '0.5', 'beta': '1', 'gamma': '5', 'deconvolution_kernel_z': 'z', 'deconvolution_kernel_y': 'y', 'deconvolution_kernel_x': 'x', 'cluster size': '400', 'min number of spots': '5', 'Interactive threshold selector': False, 'spots_extraction_folder': '', 'spots_filename': 'spots_extraction', 'do_spots_csv': False, 'do_spots_excel': False, 'do_spots_feather': False, 'output_folder': '', 'batch_name': '', 'save segmentation': False, 'save detection': False, 'extract spots': False, 'csv': False, 'xlsx': False, 'feather': True, 2: 'Output'}
|
|
2
|
+
for k in a.keys() :
|
|
3
|
+
print(k, ' : ', type(k))
|