small-fish-gui 2.0.2__py3-none-any.whl → 2.1.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 +2 -2
- small_fish_gui/batch/integrity.py +2 -2
- small_fish_gui/batch/pipeline.py +46 -11
- small_fish_gui/batch/prompt.py +102 -41
- small_fish_gui/batch/update.py +26 -13
- small_fish_gui/batch/utils.py +1 -1
- small_fish_gui/gui/__init__.py +1 -0
- small_fish_gui/gui/_napari_widgets.py +418 -6
- small_fish_gui/gui/layout.py +332 -112
- small_fish_gui/gui/napari_visualiser.py +107 -22
- small_fish_gui/gui/prompts.py +161 -48
- small_fish_gui/gui/testing.ipynb +231 -24
- small_fish_gui/gui/tooltips.py +7 -1
- small_fish_gui/hints.py +23 -7
- small_fish_gui/interface/__init__.py +7 -1
- small_fish_gui/interface/default_settings.py +118 -0
- small_fish_gui/interface/image.py +43 -11
- small_fish_gui/interface/settings.json +50 -0
- small_fish_gui/interface/testing.ipynb +4354 -0
- small_fish_gui/interface/user_settings.py +96 -0
- small_fish_gui/main_menu.py +13 -1
- small_fish_gui/pipeline/{_signaltonoise.py → _bigfish_wrapers.py} +59 -7
- small_fish_gui/pipeline/_colocalisation.py +23 -24
- small_fish_gui/pipeline/_preprocess.py +46 -32
- small_fish_gui/pipeline/actions.py +48 -5
- small_fish_gui/pipeline/detection.py +71 -141
- small_fish_gui/pipeline/segmentation.py +360 -268
- small_fish_gui/pipeline/spots.py +3 -3
- small_fish_gui/pipeline/utils.py +5 -1
- small_fish_gui/README.md → small_fish_gui-2.1.0.dist-info/METADATA +48 -8
- small_fish_gui-2.1.0.dist-info/RECORD +46 -0
- {small_fish_gui-2.0.2.dist-info → small_fish_gui-2.1.0.dist-info}/WHEEL +1 -1
- small_fish_gui/.github/workflows/python-publish.yml +0 -39
- small_fish_gui/LICENSE +0 -24
- small_fish_gui/batch/values.txt +0 -65
- small_fish_gui/default_values.py +0 -51
- small_fish_gui/gui/screenshot/general_help_screenshot.png +0 -0
- small_fish_gui/gui/screenshot/mapping_help_screenshot.png +0 -0
- small_fish_gui/gui/screenshot/segmentation_help_screenshot.png +0 -0
- small_fish_gui/illustrations/DetectionVitrine_filtre.png +0 -0
- small_fish_gui/illustrations/DetectionVitrine_signal.png +0 -0
- small_fish_gui/illustrations/FocciVitrine.png +0 -0
- small_fish_gui/illustrations/FocciVitrine_no_spots.png +0 -0
- small_fish_gui/illustrations/Segmentation2D.png +0 -0
- small_fish_gui/illustrations/Segmentation2D_with_labels.png +0 -0
- small_fish_gui/logo.png +0 -0
- small_fish_gui/pipeline/testing.ipynb +0 -3636
- small_fish_gui/requirements.txt +0 -19
- small_fish_gui-2.0.2.dist-info/METADATA +0 -75
- small_fish_gui-2.0.2.dist-info/RECORD +0 -59
- {small_fish_gui-2.0.2.dist-info → small_fish_gui-2.1.0.dist-info}/licenses/LICENSE +0 -0
small_fish_gui/gui/layout.py
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
import FreeSimpleGUI as sg
|
|
2
2
|
import os
|
|
3
|
+
import numpy as np
|
|
3
4
|
import cellpose.models as models
|
|
4
|
-
import small_fish_gui.default_values as default
|
|
5
5
|
from typing import Optional, Union
|
|
6
6
|
|
|
7
7
|
from cellpose.core import use_gpu
|
|
8
|
-
from .tooltips import FLOW_THRESHOLD_TOOLTIP,CELLPROB_TOOLTIP
|
|
8
|
+
from .tooltips import FLOW_THRESHOLD_TOOLTIP,CELLPROB_TOOLTIP, MIN_SIZE_TOOLTIP
|
|
9
9
|
from ..hints import pipeline_parameters
|
|
10
10
|
from ..utils import check_parameter
|
|
11
|
+
from ..interface import SettingsDict, get_default_settings, get_settings
|
|
11
12
|
|
|
12
13
|
|
|
14
|
+
settings = get_settings()
|
|
15
|
+
|
|
13
16
|
def add_header(header_text) :
|
|
14
17
|
"""Returns [elmnt] not layout"""
|
|
15
18
|
header = [sg.Text('\n{0}'.format(header_text), size= (len(header_text),3), font= 'bold 15')]
|
|
@@ -66,9 +69,14 @@ def parameters_layout(
|
|
|
66
69
|
] for parameter, option in zip(parameters, opt)
|
|
67
70
|
]
|
|
68
71
|
|
|
69
|
-
if
|
|
72
|
+
if isinstance(unit, str):
|
|
70
73
|
for line_id, line in enumerate(layout) :
|
|
71
74
|
layout[line_id] += [sg.Text('{0}'.format(unit))]
|
|
75
|
+
elif isinstance(unit, list) :
|
|
76
|
+
if len(unit) != len(parameters) : raise ValueError(f"unit list and parameters must have same length : {len(unit)} , {len(parameters)}")
|
|
77
|
+
|
|
78
|
+
for line_id, unit_txt in zip(range(len(parameters)), unit) :
|
|
79
|
+
layout[line_id] += [sg.Text('{0}'.format(unit_txt))]
|
|
72
80
|
|
|
73
81
|
if isinstance(header, str) :
|
|
74
82
|
layout = [add_header(header)] + layout
|
|
@@ -103,13 +111,14 @@ def tuple_layout(opt=None, default_dict={}, unit:dict={}, names : dict = {}, **t
|
|
|
103
111
|
|
|
104
112
|
return layout
|
|
105
113
|
|
|
106
|
-
def path_layout(keys= [],look_for_dir = False, header=None, preset=
|
|
114
|
+
def path_layout(keys= [],look_for_dir = False, header=None, preset=settings.working_directory) :
|
|
107
115
|
"""
|
|
108
116
|
If not look for dir then looks for file.
|
|
109
117
|
"""
|
|
110
118
|
if len(keys) == 0 : return []
|
|
111
119
|
check_parameter(keys= list, header = (str, type(None)))
|
|
112
120
|
for key in keys : check_parameter(key = str)
|
|
121
|
+
|
|
113
122
|
if look_for_dir : Browse = sg.FolderBrowse
|
|
114
123
|
else : Browse = sg.FileBrowse
|
|
115
124
|
|
|
@@ -185,105 +194,197 @@ def radio_layout(values, header=None, key=None) :
|
|
|
185
194
|
return layout
|
|
186
195
|
|
|
187
196
|
def _segmentation_layout(
|
|
188
|
-
|
|
197
|
+
is_multichannel : bool,
|
|
189
198
|
is_3D_stack : bool,
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
cytoplasm_segmentation_3D
|
|
203
|
-
nucleus_segmentation_3D
|
|
204
|
-
cellprob_threshold
|
|
205
|
-
flow_threshold
|
|
206
|
-
anisotropy
|
|
199
|
+
cytoplasm_model,
|
|
200
|
+
nucleus_model,
|
|
201
|
+
cytoplasm_channel,
|
|
202
|
+
nucleus_channel,
|
|
203
|
+
other_nucleus_image,
|
|
204
|
+
cytoplasm_diameter,
|
|
205
|
+
nucleus_diameter,
|
|
206
|
+
show_segmentation,
|
|
207
|
+
save_segmentation_visuals,
|
|
208
|
+
segment_only_nuclei,
|
|
209
|
+
saving_path,
|
|
210
|
+
filename,
|
|
211
|
+
cytoplasm_segmentation_3D ,
|
|
212
|
+
nucleus_segmentation_3D ,
|
|
213
|
+
cellprob_threshold ,
|
|
214
|
+
flow_threshold ,
|
|
215
|
+
anisotropy,
|
|
216
|
+
cytoplasm_min_size : int,
|
|
217
|
+
nucleus_min_size : int,
|
|
218
|
+
reordered_shape : tuple,
|
|
219
|
+
**kwargs
|
|
207
220
|
) :
|
|
208
221
|
|
|
209
222
|
USE_GPU = use_gpu()
|
|
210
|
-
|
|
211
|
-
models_list = models.get_user_models() + models.MODEL_NAMES
|
|
212
|
-
if len(models_list) == 0 : models_list = ['no model found']
|
|
223
|
+
event_dict = dict()
|
|
213
224
|
|
|
214
225
|
#Header : GPU availabality
|
|
215
|
-
layout = [
|
|
216
|
-
|
|
217
|
-
|
|
226
|
+
layout = [[sg.Text("Cell Segmentation", font="bold 20", pad=(0,20))]]
|
|
227
|
+
layout += [[sg.Text("GPU is currently "), sg.Text('ON', text_color= 'green') if USE_GPU else sg.Text('OFF', text_color= 'red')]]
|
|
228
|
+
layout += bool_layout(['Interactive segmentation'],keys=['show_segmentation'], preset= show_segmentation)
|
|
229
|
+
|
|
230
|
+
segment_only_nuclei_checkbox = sg.Checkbox("Segment only nuclei", default=segment_only_nuclei, key= "segment_only_nuclei", enable_events=True)
|
|
231
|
+
layout += [[segment_only_nuclei_checkbox]]
|
|
232
|
+
event_dict['segment_only_nuclei'] = segment_only_nuclei_checkbox
|
|
218
233
|
|
|
219
|
-
#cytoplasm parameters
|
|
220
|
-
layout += [
|
|
221
|
-
add_header("Cytoplasm Segmentation"),
|
|
222
|
-
[sg.Text("Choose parameters for cytoplasm segmentation: \n")],
|
|
223
|
-
]
|
|
224
|
-
|
|
225
|
-
if is_3D_stack : layout += bool_layout(['3D segmentation'], preset=[cytoplasm_segmentation_3D], keys=['cytoplasm_segmentation_3D'],)
|
|
226
|
-
if multichannel : layout += parameters_layout(['Cytoplasm channel'],default_values= [cytoplasm_channel_preset], keys = ["cytoplasm_channel"])
|
|
227
|
-
|
|
228
|
-
layout += [[sg.Text("Cellpose model : ")] + combo_elmt(models_list, key='cyto_model_name', default_value= cytoplasm_model_preset)]
|
|
229
|
-
layout += parameters_layout(['Cytoplasm diameter'], unit= "px", default_values= [cyto_diameter_preset], keys=['cytoplasm_diameter'])
|
|
230
|
-
layout += parameters_layout(
|
|
231
|
-
["Flow threshold", "Cellprob threshold"],
|
|
232
|
-
default_values=[flow_threshold, cellprob_threshold],
|
|
233
|
-
keys=["flow_threshold_cyto","cellprob_threshold_cyto"],
|
|
234
|
-
tooltips= [FLOW_THRESHOLD_TOOLTIP, CELLPROB_TOOLTIP]
|
|
235
|
-
)
|
|
236
|
-
|
|
237
234
|
#Nucleus parameters
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
235
|
+
nucleus_key = "nucleus"
|
|
236
|
+
layout += [[sg.Text("Nucleus parameters", font="bold 15", pad=(0,10))]]
|
|
237
|
+
nucleus_parameters_col, nucleus_event_dict = _segmentate_object_layout(
|
|
238
|
+
reordered_shape = reordered_shape,
|
|
239
|
+
anisotropy=anisotropy,
|
|
240
|
+
cellprob_threshold=cellprob_threshold,
|
|
241
|
+
channel=nucleus_channel,
|
|
242
|
+
diameter=nucleus_diameter,
|
|
243
|
+
flow_threshold=flow_threshold,
|
|
244
|
+
is_3D_stack=is_3D_stack,
|
|
245
|
+
model=nucleus_model,
|
|
246
|
+
is_multichannel=is_multichannel,
|
|
247
|
+
object_key=nucleus_key,
|
|
248
|
+
segmentation_3D=nucleus_segmentation_3D,
|
|
249
|
+
min_size=nucleus_min_size
|
|
250
|
+
)
|
|
251
|
+
layout += path_layout(keys=["other_nucleus_image"], look_for_dir=False, preset=other_nucleus_image)
|
|
252
|
+
layout += [[nucleus_parameters_col]]
|
|
253
|
+
event_dict.update(nucleus_event_dict)
|
|
254
|
+
event_dict[nucleus_key + "_column"] = nucleus_parameters_col
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
#Cytoplasm parameters
|
|
258
|
+
layout += [[sg.Text("Cytoplasm parameters", font="bold 15", pad=(0,10))]]
|
|
259
|
+
cytoplasm_key = "cytoplasm"
|
|
260
|
+
cytoplasm_parameters_col, cytoplasm_event_dict = _segmentate_object_layout(
|
|
261
|
+
reordered_shape = reordered_shape,
|
|
262
|
+
anisotropy=anisotropy,
|
|
263
|
+
cellprob_threshold=cellprob_threshold,
|
|
264
|
+
channel=cytoplasm_channel,
|
|
265
|
+
diameter=cytoplasm_diameter,
|
|
266
|
+
flow_threshold=flow_threshold,
|
|
267
|
+
is_3D_stack=is_3D_stack,
|
|
268
|
+
model=cytoplasm_model,
|
|
269
|
+
is_multichannel=is_multichannel,
|
|
270
|
+
object_key=cytoplasm_key,
|
|
271
|
+
segmentation_3D=cytoplasm_segmentation_3D,
|
|
272
|
+
min_size=cytoplasm_min_size
|
|
273
|
+
)
|
|
274
|
+
layout += [[cytoplasm_parameters_col]]
|
|
275
|
+
event_dict.update(cytoplasm_event_dict)
|
|
276
|
+
event_dict[cytoplasm_key + "_column"] = cytoplasm_parameters_col
|
|
277
|
+
|
|
278
|
+
#Control plots
|
|
279
|
+
layout += [[sg.Text("Control plots", font="bold 15", pad=(0,10))]]
|
|
280
|
+
layout += bool_layout(['Save png control'], preset= save_segmentation_visuals, keys=['save_segmentation_visuals'])
|
|
281
|
+
layout += path_layout(keys=['seg_control_saving_path'], look_for_dir=True, preset=saving_path)
|
|
282
|
+
layout += parameters_layout(['Filename'], default_values=[filename], size= 25, keys=['filename'])
|
|
283
|
+
|
|
284
|
+
return layout, event_dict
|
|
285
|
+
|
|
286
|
+
def _segmentate_object_layout(
|
|
287
|
+
reordered_shape : tuple | None,
|
|
288
|
+
object_key : str,
|
|
289
|
+
is_multichannel : bool,
|
|
290
|
+
is_3D_stack : bool,
|
|
291
|
+
model : str,
|
|
292
|
+
channel : int,
|
|
293
|
+
diameter : int,
|
|
294
|
+
segmentation_3D : bool ,
|
|
295
|
+
cellprob_threshold : float ,
|
|
296
|
+
flow_threshold : float,
|
|
297
|
+
anisotropy : float,
|
|
298
|
+
min_size : int,
|
|
299
|
+
**kwargs
|
|
300
|
+
) -> sg.Column :
|
|
301
|
+
|
|
302
|
+
models_list = models.get_user_models() + models.MODEL_NAMES
|
|
303
|
+
if len(models_list) == 0 : models_list = ['no model found']
|
|
304
|
+
|
|
305
|
+
key_2D = object_key + "_radio_2D"
|
|
306
|
+
options_2D = list()
|
|
307
|
+
key_3D = object_key + "_radio_3D"
|
|
308
|
+
options_3D = list()
|
|
309
|
+
layout = []
|
|
310
|
+
|
|
311
|
+
radio_2D_seg = sg.Radio("2D segmentation", group_id=object_key+"_seg_dim", default=not segmentation_3D, visible = True, enable_events=True, key=key_2D)
|
|
312
|
+
radio_max_proj = sg.Radio("max proj", group_id=object_key+"_2D_proj", default=False, disabled= segmentation_3D, key= object_key+"_max_proj")
|
|
313
|
+
radio_mean_proj = sg.Radio("mean proj", group_id=object_key+"_2D_proj", default=True, disabled= segmentation_3D, key = object_key + "_mean_proj")
|
|
314
|
+
radio_slice_proj = sg.Radio("select slice", group_id=object_key+"_2D_proj", default=False, disabled= segmentation_3D, key=object_key + "_select_slice")
|
|
315
|
+
radio_3D_seg = sg.Radio("3D segmentation", group_id=object_key+"_seg_dim", default=segmentation_3D, visible = True, enable_events=True, key= key_3D)
|
|
316
|
+
anisotropy = sg.Input(default_text = 1, key = object_key + "_anisotropy",size=5, disabled=not segmentation_3D)
|
|
317
|
+
|
|
318
|
+
if is_3D_stack :
|
|
319
|
+
slice_number = reordered_shape[0 + is_multichannel] if not reordered_shape is None else 999
|
|
320
|
+
int_slice_proj = sg.Spin(list(range(slice_number)), size= (5,1), disabled= segmentation_3D, key=object_key+"_selected_slice")
|
|
321
|
+
|
|
322
|
+
options_2D += [
|
|
323
|
+
radio_max_proj,
|
|
324
|
+
radio_mean_proj,
|
|
325
|
+
radio_slice_proj,
|
|
326
|
+
int_slice_proj
|
|
327
|
+
]
|
|
328
|
+
|
|
329
|
+
layout += [
|
|
330
|
+
[radio_2D_seg],
|
|
331
|
+
[sg.Column([[radio_max_proj, radio_mean_proj, radio_slice_proj, int_slice_proj]], pad= (15,0,0,5))]
|
|
241
332
|
]
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
layout += [
|
|
336
|
+
[radio_3D_seg],
|
|
337
|
+
[sg.Column([[sg.Text("anisotropy"), anisotropy]], pad=(15,0,0,5))]
|
|
338
|
+
]
|
|
339
|
+
|
|
340
|
+
options_3D += [
|
|
341
|
+
anisotropy
|
|
342
|
+
]
|
|
343
|
+
|
|
344
|
+
if is_multichannel :
|
|
345
|
+
channel_elmt = sg.Input(channel, key=object_key + "_channel", size=5)
|
|
346
|
+
layout += [[sg.Text(f'{object_key.capitalize()} channel'), channel_elmt]]
|
|
347
|
+
|
|
348
|
+
layout += [[sg.Text("Cellpose model : ")] + combo_elmt(models_list, key=object_key +'_model_name', default_value= model)]
|
|
349
|
+
layout += parameters_layout([f'{object_key.capitalize()} diameter'], unit= "px", default_values= [diameter], keys=[object_key+'_diameter'])
|
|
250
350
|
layout += parameters_layout(
|
|
251
|
-
["Flow threshold", "Cellprob threshold"],
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
if is_3D_stack : layout += parameters_layout(
|
|
257
|
-
['anisotropy'],
|
|
258
|
-
header = "Model parameters",
|
|
259
|
-
default_values = [anisotropy]
|
|
351
|
+
["Flow threshold", "Cellprob threshold", "Min. size"],
|
|
352
|
+
unit=["","","px"],
|
|
353
|
+
default_values=[flow_threshold, cellprob_threshold, min_size],
|
|
354
|
+
keys=[object_key + "_flow_threshold",object_key + "_cellprob_threshold", object_key + "_min_size"],
|
|
355
|
+
tooltips= [FLOW_THRESHOLD_TOOLTIP, CELLPROB_TOOLTIP, MIN_SIZE_TOOLTIP]
|
|
260
356
|
)
|
|
261
357
|
|
|
262
|
-
|
|
263
|
-
layout += bool_layout(['Show_segmentation'],keys=['show_segmentation'], header= 'Segmentation plots', preset= show_segmentation_preset)
|
|
264
|
-
layout += bool_layout(['Save segmentation visual'], preset= save_segmentation_visual_preset, keys=['save_segmentation_visual'])
|
|
265
|
-
layout += path_layout(keys=['saving path'], look_for_dir=True, preset=saving_path_preset)
|
|
266
|
-
layout += parameters_layout(['filename'], default_values=[filename_preset], size= 25)
|
|
358
|
+
object_col = sg.Column(layout)
|
|
267
359
|
|
|
268
|
-
|
|
360
|
+
#Reference dict
|
|
361
|
+
event_dict = {
|
|
362
|
+
key_2D : options_2D,
|
|
363
|
+
key_3D : options_3D,
|
|
364
|
+
object_key + "_radio_2D_seg" : radio_2D_seg,
|
|
365
|
+
object_key + "_radio_3D_seg" : radio_3D_seg,
|
|
366
|
+
object_key + "_channel" : channel_elmt, # For batch mode layout update
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
return object_col, event_dict
|
|
370
|
+
|
|
269
371
|
|
|
270
372
|
def _input_parameters_layout(
|
|
271
|
-
ask_for_segmentation,
|
|
272
|
-
is_3D_stack_preset,
|
|
273
|
-
time_stack_preset,
|
|
274
|
-
multichannel_preset,
|
|
275
|
-
do_dense_regions_deconvolution_preset,
|
|
276
|
-
do_clustering_preset,
|
|
277
|
-
do_segmentation_preset,
|
|
278
|
-
do_Napari_correction
|
|
279
|
-
|
|
280
|
-
) :
|
|
373
|
+
ask_for_segmentation : bool,
|
|
374
|
+
is_3D_stack_preset : bool,
|
|
375
|
+
time_stack_preset : bool,
|
|
376
|
+
multichannel_preset : bool,
|
|
377
|
+
do_dense_regions_deconvolution_preset : bool,
|
|
378
|
+
do_clustering_preset : bool,
|
|
379
|
+
do_segmentation_preset : bool,
|
|
380
|
+
do_Napari_correction : bool
|
|
381
|
+
) :
|
|
281
382
|
layout_image_path = path_layout(['image_path'], header= "Image")
|
|
282
383
|
layout_image_path += bool_layout(['3D stack', 'Multichannel stack'], keys=['is_3D_stack', 'is_multichannel'], preset= [is_3D_stack_preset, multichannel_preset])
|
|
283
384
|
|
|
284
385
|
layout_image_path += bool_layout(
|
|
285
386
|
['Dense regions deconvolution', 'Compute clusters', 'Cell segmentation', 'Open Napari corrector'],
|
|
286
|
-
keys= ['do_dense_regions_deconvolution', 'do_cluster_computation', 'do_segmentation',
|
|
387
|
+
keys= ['do_dense_regions_deconvolution', 'do_cluster_computation', 'do_segmentation','show_napari_corrector' ],
|
|
287
388
|
preset= [do_dense_regions_deconvolution_preset, do_clustering_preset, do_segmentation_preset, do_Napari_correction],
|
|
288
389
|
header= "Pipeline settings")
|
|
289
390
|
|
|
@@ -298,21 +399,24 @@ def _detection_layout(
|
|
|
298
399
|
do_segmentation,
|
|
299
400
|
segmentation_done=False,
|
|
300
401
|
default_dict : pipeline_parameters={},
|
|
301
|
-
) :
|
|
402
|
+
) :
|
|
302
403
|
if is_3D_stack : dim = 3
|
|
303
404
|
else : dim = 2
|
|
405
|
+
default = get_settings()
|
|
304
406
|
|
|
305
407
|
#Detection
|
|
306
408
|
detection_parameters = ['threshold', 'threshold penalty']
|
|
307
|
-
default_detection = [default_dict.setdefault('threshold',default.
|
|
409
|
+
default_detection = [default_dict.setdefault('threshold',default.threshold), default_dict.setdefault('threshold penalty', default.threshold_penalty)]
|
|
308
410
|
opt= [True, True]
|
|
411
|
+
parameters_keys = ['threshold', 'threshold_penalty']
|
|
309
412
|
if is_multichannel :
|
|
310
|
-
detection_parameters += ['
|
|
413
|
+
detection_parameters += ['channel to compute']
|
|
311
414
|
opt += [False]
|
|
312
|
-
|
|
415
|
+
parameters_keys += ['channel_to_compute']
|
|
416
|
+
default_detection += [default_dict.setdefault('channel_to_compute', default.detection_channel)]
|
|
313
417
|
|
|
314
418
|
layout = [[sg.Text("Green parameters", text_color= 'green'), sg.Text(" are optional parameters.")]]
|
|
315
|
-
layout += parameters_layout(detection_parameters, header= 'Detection', opt=opt, default_values=default_detection)
|
|
419
|
+
layout += parameters_layout(detection_parameters, header= 'Detection', opt=opt, default_values=default_detection, keys= parameters_keys)
|
|
316
420
|
|
|
317
421
|
if dim == 2 : tuple_shape = ('y','x')
|
|
318
422
|
else : tuple_shape = ('z','y','x')
|
|
@@ -323,26 +427,26 @@ def _detection_layout(
|
|
|
323
427
|
layout += tuple_layout(opt=opt, unit=unit, default_dict=default_dict, names=names, voxel_size= tuple_shape, spot_size= tuple_shape, log_kernel_size= tuple_shape, minimum_distance= tuple_shape)
|
|
324
428
|
|
|
325
429
|
if (do_segmentation and is_multichannel) or (is_multichannel and segmentation_done):
|
|
326
|
-
layout += [[sg.Text("nucleus channel signal "), sg.InputText(default_text=default_dict.setdefault('nucleus_channel',default.
|
|
430
|
+
layout += [[sg.Text("nucleus channel signal "), sg.InputText(default_text=default_dict.setdefault('nucleus_channel',default.nucleus_channel), key= "nucleus channel signal", size= 5, tooltip= "Channel from which signal will be measured for nucleus features, \nallowing you to measure signal from a different channel than the one used for segmentation.")]]
|
|
327
431
|
|
|
328
432
|
#Deconvolution
|
|
329
433
|
if do_dense_region_deconvolution :
|
|
330
|
-
default_dense_regions_deconvolution = [default_dict.setdefault('alpha',default.
|
|
434
|
+
default_dense_regions_deconvolution = [default_dict.setdefault('alpha',default.alpha), default_dict.setdefault('beta',default.beta)]
|
|
331
435
|
layout += parameters_layout(['alpha', 'beta',], default_values= default_dense_regions_deconvolution, header= 'do_dense_regions_deconvolution')
|
|
332
|
-
layout += parameters_layout(['gamma'], unit= 'px', default_values= [default_dict.setdefault('gamma',default.
|
|
436
|
+
layout += parameters_layout(['gamma'], unit= 'px', default_values= [default_dict.setdefault('gamma',default.gamma)])
|
|
333
437
|
layout += tuple_layout(opt= {"deconvolution_kernel" : True}, unit= {"deconvolution_kernel" : 'px'}, default_dict=default_dict, deconvolution_kernel = tuple_shape)
|
|
334
438
|
|
|
335
439
|
#Clustering
|
|
336
440
|
if do_clustering :
|
|
337
|
-
layout += parameters_layout(['Cluster radius'],keys=['cluster_size'], unit="radius(nm)", default_values=[default_dict.setdefault('cluster_size',default.
|
|
338
|
-
layout += parameters_layout(['Min nb spots per cluster'],keys=['min_number_of_spots'], default_values=[default_dict.setdefault('min_number_of_spots', default.
|
|
441
|
+
layout += parameters_layout(['Cluster radius'],keys=['cluster_size'], unit="radius(nm)", default_values=[default_dict.setdefault('cluster_size',default.cluster_size)])
|
|
442
|
+
layout += parameters_layout(['Min nb spots per cluster'],keys=['min_number_of_spots'], default_values=[default_dict.setdefault('min_number_of_spots', default.min_spot)])
|
|
339
443
|
|
|
340
|
-
layout += bool_layout(['Interactive threshold selector'],keys = ['show_interactive_threshold_selector'], preset=[default.
|
|
444
|
+
layout += bool_layout(['Interactive threshold selector'],keys = ['show_interactive_threshold_selector'], preset=[default.interactive_threshold_selector])
|
|
341
445
|
layout += path_layout(
|
|
342
446
|
keys=['spots_extraction_folder'],
|
|
343
447
|
look_for_dir=True,
|
|
344
448
|
header= "Individual spot extraction",
|
|
345
|
-
preset= default_dict.setdefault('spots_extraction_folder', default.
|
|
449
|
+
preset= default_dict.setdefault('spots_extraction_folder', default.spot_extraction_folder)
|
|
346
450
|
)
|
|
347
451
|
default_filename = default_dict.setdefault("filename","") + "_spot_extraction"
|
|
348
452
|
layout += parameters_layout(
|
|
@@ -353,39 +457,155 @@ def _detection_layout(
|
|
|
353
457
|
layout += bool_layout(
|
|
354
458
|
['.csv','.excel',],
|
|
355
459
|
keys= ['do_spots_csv', 'do_spots_excel'],
|
|
356
|
-
preset= [default_dict.setdefault('do_spots_csv',default.
|
|
460
|
+
preset= [default_dict.setdefault('do_spots_csv',default.do_csv), default_dict.setdefault('do_spots_excel',default.do_excel),]
|
|
357
461
|
)
|
|
358
462
|
|
|
359
463
|
return layout
|
|
360
464
|
|
|
361
|
-
def colocalization_layout(spot_list : list) :
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
465
|
+
def colocalization_layout(spot_list : list, **default_values) :
|
|
466
|
+
default = get_settings()
|
|
467
|
+
|
|
468
|
+
element_dict = {}
|
|
469
|
+
can_use_memory = len(spot_list) != 0
|
|
470
|
+
|
|
471
|
+
for spot_id in [1,2] :
|
|
472
|
+
element_dict[f"radio_spots{spot_id}_memory"] = sg.Radio("From memory : ", group_id = spot_id, enable_events = True, key = f"radio_spots{spot_id}_memory", default= can_use_memory or default_values.get(f"radio_spots{spot_id}_memory"), disabled= not can_use_memory)
|
|
473
|
+
element_dict[f"radio_spots{spot_id}_load"] = sg.Radio("Load spot detection : ", group_id = spot_id, enable_events = True, key = f"radio_spots{spot_id}_load", default= (not can_use_memory) or (default_values.get(f"radio_spots{spot_id}_load")))
|
|
474
|
+
|
|
475
|
+
element_dict[f"spots{spot_id}_browse"] = [
|
|
476
|
+
sg.Input(size=20, key= f"spots{spot_id}_browse", default_text=default_values.get(f"spots{spot_id}_browse"), disabled=can_use_memory and not default_values.get(f"radio_spots{spot_id}_load")),
|
|
477
|
+
sg.FileBrowse(key=f"spots{spot_id}_browsebutton", initial_folder=default_values.setdefault(f"spots{spot_id}_browsebutton", default_values["working_directory"]), disabled=can_use_memory and not default_values.get(f"radio_spots{spot_id}_load")),
|
|
478
|
+
]
|
|
479
|
+
element_dict[f"spots{spot_id}_voxel_size"] = [
|
|
480
|
+
sg.Text("voxel size"),
|
|
481
|
+
sg.Input(size= 5, key= f"z_voxel_size_spot{spot_id}", default_text= default_values.setdefault(f"z_voxel_size_spot{spot_id}", "z"), disabled=can_use_memory and not default_values.get(f"radio_spots{spot_id}_load")),
|
|
482
|
+
sg.Input(size= 5, key= f"y_voxel_size_spot{spot_id}", default_text= default_values.setdefault(f"y_voxel_size_spot{spot_id}", "y"), disabled=can_use_memory and not default_values.get(f"radio_spots{spot_id}_load")),
|
|
483
|
+
sg.Input(size= 5, key= f"x_voxel_size_spot{spot_id}", default_text= default_values.setdefault(f"x_voxel_size_spot{spot_id}", "x"), disabled=can_use_memory and not default_values.get(f"radio_spots{spot_id}_load")),
|
|
484
|
+
]
|
|
485
|
+
|
|
486
|
+
#Ref for updating
|
|
487
|
+
element_dict[f"options_spots{spot_id}_memory"] = sg.Col(
|
|
488
|
+
[[sg.DropDown(values=[""] + spot_list, key=f"spots{spot_id}_dropdown", size= 10, disabled= not can_use_memory or default_values.get(f"radio_spots{spot_id}_load"), default_value= default_values.setdefault(f"spots{spot_id}_dropdown", ""))]]
|
|
489
|
+
)
|
|
490
|
+
element_dict[f"options_spots{spot_id}_load"] = sg.Col(
|
|
491
|
+
[element_dict[f"spots{spot_id}_browse"], element_dict[f"spots{spot_id}_voxel_size"]]
|
|
492
|
+
)
|
|
493
|
+
|
|
494
|
+
col1 = sg.Col([
|
|
365
495
|
[sg.Text("Spots 1", size = 10)],
|
|
366
|
-
[
|
|
496
|
+
[element_dict["radio_spots1_memory"]],
|
|
497
|
+
[element_dict["options_spots1_memory"]],
|
|
498
|
+
[element_dict["radio_spots1_load"]],
|
|
499
|
+
[element_dict["options_spots1_load"]],
|
|
500
|
+
])
|
|
501
|
+
|
|
502
|
+
col2 = sg.Col([
|
|
367
503
|
[sg.Text("Spots 2", size = 10)],
|
|
368
|
-
[
|
|
504
|
+
[element_dict["radio_spots2_memory"]],
|
|
505
|
+
[element_dict["options_spots2_memory"]],
|
|
506
|
+
[element_dict["radio_spots2_load"]],
|
|
507
|
+
[element_dict["options_spots2_load"]],
|
|
508
|
+
])
|
|
509
|
+
|
|
510
|
+
layout = [
|
|
511
|
+
[sg.Push(), sg.Text("Co-localization", size=50, font="bold"), sg.Push()],
|
|
512
|
+
[sg.VPush()],
|
|
513
|
+
[col1,col2]
|
|
514
|
+
]
|
|
515
|
+
layout += parameters_layout(['colocalisation distance'], unit= 'nm', default_values= [default_values.setdefault('colocalisation_distance', default_values["coloc_range"])])
|
|
516
|
+
layout += [[sg.Button("Ok", bind_return_key=True),sg.Button("Cancel"),sg.Push(),],
|
|
517
|
+
[sg.VPush()]
|
|
369
518
|
]
|
|
370
519
|
|
|
371
|
-
layout
|
|
520
|
+
return layout, element_dict
|
|
372
521
|
|
|
373
|
-
|
|
374
|
-
layout += [[sg.Text(" 'voxel size' is used only for loaded spot lists.")]]
|
|
522
|
+
def settings_layout(default_values : SettingsDict = get_default_settings()) :
|
|
375
523
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
524
|
+
if not isinstance(default_values, SettingsDict) : raise TypeError(f"Incorect type for default_values : {type(default_values)}; expected SettingsDict")
|
|
525
|
+
models_list = models.get_user_models() + models.MODEL_NAMES
|
|
526
|
+
|
|
527
|
+
layout = [[sg.Text("Default values", font="ArialBold 20")]]
|
|
528
|
+
layout += [[sg.Text("Default working directory"), sg.Input(default_text=default_values.working_directory, key= "working_directory"), sg.FolderBrowse()]]
|
|
529
|
+
|
|
530
|
+
image_layout = [[sg.Text("Image", font="ArialBold 15")]]
|
|
531
|
+
image_layout += bool_layout(['Multichannel stack', '3D stack'],preset= [default_values.multichannel_stack, default_values.stack_3D], keys=["multichannel_stack", "stack_3D"])
|
|
532
|
+
image_layout += parameters_layout(['Detection channel', 'Nucleus channel'],default_values=[default_values.detection_channel, default_values.nucleus_channel], keys=['detection_channel', 'nucleus_channel'])
|
|
533
|
+
|
|
534
|
+
segmentation_layout = [[sg.Text("Segmentation", font="ArialBold 15")],
|
|
535
|
+
[sg.Text("Cytoplasm model : "), sg.DropDown(models_list, default_value=default_values.cytoplasm_model, key= "cytoplasm_model")],
|
|
536
|
+
[sg.Radio(default= default_values.cytoplasm_mean_proj, group_id=0, key="cytoplasm_mean_proj", text= "mean proj"), sg.Radio(default=default_values.cytoplasm_max_proj, group_id=0, key="cytoplasm_max_proj", text= "max proj"), sg.Radio(default= default_values.cytoplasm_select_slice, group_id=0, key="cytoplasm_select_slice", text= "single slice"), sg.Input(default_values.cytoplasm_selected_slice, size=5, key= "cytoplasm_selected_slice")],
|
|
537
|
+
[sg.Text("Nucleus model : "), sg.DropDown(models_list, default_value=default_values.nucleus_model, key= "nucleus_model")],
|
|
538
|
+
[sg.Radio(default= default_values.nucleus_mean_proj, group_id=1, key="nucleus_mean_proj", text= "mean proj"), sg.Radio(default= default_values.nucleus_max_proj, group_id=1, key="nucleus_max_proj", text= "max proj"), sg.Radio(default= default_values.nucleus_select_slice, group_id=1, key="nucleus_select_slice", text= "single slice"), sg.Input(default_values.nucleus_selected_slice, size=5, key= "nucleus_selected_slice")],
|
|
539
|
+
]
|
|
540
|
+
segmentation_layout += parameters_layout(
|
|
541
|
+
["Flow threshold", "Cellprob threshold", "Cytoplasm diameter", "Cytoplasm min size", "Nucleus diameter", "Nucleus min size", "Anisotropy"],
|
|
542
|
+
default_values= [default_values.flow_threshold, default_values.cellprob_threshold, default_values.cytoplasm_diameter, default_values.cytoplasm_min_size, default_values.nucleus_diameter, default_values.nucleus_min_size, default_values.anisotropy],
|
|
543
|
+
keys=["flow_threshold", "cellprob_threshold", "cytoplasm_diameter", "cytoplasm_min_size", "nucleus_diameter", "nucleus_min_size", "anisotropy"])
|
|
544
|
+
segmentation_layout += bool_layout(
|
|
545
|
+
["show segmentation", "segment only nuclei", "do 3D segmentation", "save segmentation visual"],
|
|
546
|
+
preset=[default_values.show_segmentation, default_values.segment_only_nuclei, default_values.do_3D_segmentation, default_values.save_segmentation_visuals],
|
|
547
|
+
keys= ["show_segmentation", "segment_only_nuclei", "do_3D_segmentation","save_segmentation_visuals"])
|
|
548
|
+
|
|
549
|
+
detection_layout = [[sg.Text("Detection", font="ArialBold 15")]]
|
|
550
|
+
detection_layout += parameters_layout(
|
|
551
|
+
["Threshold", "Threshold penalty"],
|
|
552
|
+
default_values=[default_values.threshold, default_values.threshold_penalty],
|
|
553
|
+
keys=["threshold", "threshold_penalty"])
|
|
554
|
+
detection_layout += bool_layout(
|
|
555
|
+
["Dense regions deconvolution", "Cluster computation", "show napari corrector", "Autofloresnce background removal", "interactive threshold selector"],
|
|
556
|
+
preset=[default_values.do_dense_regions_deconvolution, default_values.do_cluster, default_values.show_napari_corrector, default_values.do_background_removal, default_values.interactive_threshold_selector],
|
|
557
|
+
keys=["do_dense_regions_deconvolution", "do_cluster", "show_napari_corrector","do_background_removal", "interactive_threshold_selector"])
|
|
558
|
+
|
|
559
|
+
deconvolution_layout = [[sg.Text("Dense regions deconvolution", font="ArialBold 15")]]
|
|
560
|
+
deconvolution_layout += parameters_layout(
|
|
561
|
+
["alpha", "beta", "gamma"],
|
|
562
|
+
default_values=[default_values.alpha, default_values.beta, default_values.gamma]
|
|
563
|
+
)
|
|
564
|
+
|
|
565
|
+
clustering_layout = [[sg.Text("Cluster computation", font="ArialBold 15")]]
|
|
566
|
+
clustering_layout += parameters_layout(
|
|
567
|
+
["Cluster size", "Min spot number"],
|
|
568
|
+
default_values=[default_values.cluster_size, default_values.min_spot],
|
|
569
|
+
keys=["cluster_size", "min_spot"])
|
|
570
|
+
|
|
571
|
+
coloc_layout = [[sg.Text("Co-localization computation", font="ArialBold 15")]]
|
|
572
|
+
coloc_layout += parameters_layout(['Co-localization range'],
|
|
573
|
+
default_values=[default_values.coloc_range],
|
|
574
|
+
keys=['coloc_range'])
|
|
575
|
+
coloc_layout += tuple_layout(default_dict= {
|
|
576
|
+
'voxel_size_z' : default_values.voxel_size[0],
|
|
577
|
+
'voxel_size_y' : default_values.voxel_size[1],
|
|
578
|
+
'voxel_size_x' : default_values.voxel_size[2],
|
|
579
|
+
}, voxel_size=('z','y','x'))
|
|
580
|
+
|
|
581
|
+
spot_extraction_layout = [[sg.Text("Spots extraction", font="ArialBold 15")]]
|
|
582
|
+
spot_extraction_layout += bool_layout(
|
|
583
|
+
["do csv", "do excel"],
|
|
584
|
+
preset=[default_values.do_csv, default_values.do_excel],
|
|
585
|
+
keys=["do_csv", "do_excel"]
|
|
586
|
+
)
|
|
587
|
+
spot_extraction_layout += [[sg.Text("spot extraction folder"), sg.Input(default_text=default_values.spot_extraction_folder, key="spot_extraction_folder", size=7) ,sg.FolderBrowse()]]
|
|
588
|
+
|
|
589
|
+
background_removing_layout = [[sg.Text("Background removing (batch)", font="ArialBold 15")]]
|
|
590
|
+
background_removing_layout += [
|
|
591
|
+
[sg.Checkbox("Remove background :", key= "do_background_removal", default= settings.do_background_removal)],
|
|
592
|
+
[sg.Text("Background channel : "), sg.Input(settings.background_channel, key = "background_channel", size= 5)]
|
|
593
|
+
]
|
|
594
|
+
|
|
595
|
+
layout += [[sg.Col(image_layout, vertical_alignment='top', expand_x = True), sg.Col(background_removing_layout, vertical_alignment='top', expand_x = True)]]
|
|
596
|
+
layout += [[sg.Col(segmentation_layout, vertical_alignment='top', expand_x = True), sg.Col(detection_layout, vertical_alignment='top', expand_x = True)]]
|
|
597
|
+
layout += [[sg.Col(deconvolution_layout, vertical_alignment='top', expand_x = True), sg.Col(clustering_layout, vertical_alignment='top', expand_x = True)]]
|
|
598
|
+
layout += [[sg.Col(spot_extraction_layout, vertical_alignment='top', expand_x = True), sg.Col(coloc_layout, vertical_alignment='top', expand_x = True)]]
|
|
379
599
|
|
|
380
600
|
return layout
|
|
381
601
|
|
|
382
602
|
def _ask_channel_map_layout(
|
|
383
603
|
shape,
|
|
384
604
|
is_3D_stack,
|
|
385
|
-
|
|
605
|
+
is_multichannel,
|
|
386
606
|
is_time_stack,
|
|
387
607
|
preset_map={},
|
|
388
|
-
) :
|
|
608
|
+
) :
|
|
389
609
|
|
|
390
610
|
x = preset_map.setdefault('x',0)
|
|
391
611
|
y = preset_map.setdefault('y',0)
|
|
@@ -394,11 +614,11 @@ def _ask_channel_map_layout(
|
|
|
394
614
|
t = preset_map.setdefault('t',0)
|
|
395
615
|
|
|
396
616
|
layout = [
|
|
397
|
-
|
|
617
|
+
[sg.Text("Dimensions mapping", font= "bold 15"), sg.Text("Image shape : {0}".format(shape))]
|
|
398
618
|
]
|
|
399
619
|
layout += parameters_layout(['x','y'], default_values=[x,y])
|
|
400
620
|
if is_3D_stack : layout += parameters_layout(['z'], default_values=[z])
|
|
401
|
-
if
|
|
621
|
+
if is_multichannel : layout += parameters_layout(['c'], default_values=[c])
|
|
402
622
|
if is_time_stack : layout += parameters_layout(['t'], default_values=[t])
|
|
403
623
|
|
|
404
624
|
return layout
|