small-fish-gui 1.10.4__py3-none-any.whl → 2.0.2__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/README.md +54 -69
- small_fish_gui/__init__.py +9 -3
- small_fish_gui/__main__.py +1 -1
- small_fish_gui/batch/integrity.py +8 -1
- small_fish_gui/batch/output.py +16 -0
- small_fish_gui/batch/pipeline.py +43 -24
- small_fish_gui/batch/prompt.py +44 -26
- small_fish_gui/batch/update.py +19 -3
- small_fish_gui/batch/utils.py +2 -0
- small_fish_gui/batch/values.txt +5 -5
- small_fish_gui/default_values.py +51 -0
- small_fish_gui/gui/__init__.py +3 -1
- small_fish_gui/gui/_napari_widgets.py +15 -4
- small_fish_gui/gui/layout.py +123 -54
- small_fish_gui/gui/napari_visualiser.py +12 -8
- small_fish_gui/gui/prompts.py +61 -74
- small_fish_gui/gui/tooltips.py +15 -0
- small_fish_gui/hints.py +23 -4
- 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/main.py → main_menu.py} +16 -15
- small_fish_gui/pipeline/_colocalisation.py +60 -41
- small_fish_gui/pipeline/_preprocess.py +13 -12
- small_fish_gui/pipeline/actions.py +102 -14
- small_fish_gui/pipeline/detection.py +5 -1
- small_fish_gui/pipeline/segmentation.py +206 -73
- small_fish_gui/pipeline/spots.py +129 -5
- small_fish_gui/pipeline/testing.ipynb +1571 -2
- small_fish_gui/requirements.txt +4 -4
- {small_fish_gui-1.10.4.dist-info → small_fish_gui-2.0.2.dist-info}/METADATA +14 -16
- small_fish_gui-2.0.2.dist-info/RECORD +59 -0
- small_fish_gui-1.10.4.dist-info/RECORD +0 -49
- {small_fish_gui-1.10.4.dist-info → small_fish_gui-2.0.2.dist-info}/WHEEL +0 -0
- {small_fish_gui-1.10.4.dist-info → small_fish_gui-2.0.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
|
|
2
|
+
CELLPROB_TOOLTIP = """ (float) from -6. to +6.
|
|
3
|
+
The network predicts 3 outputs: flows in X, flows in Y, and cell “probability”.
|
|
4
|
+
The predictions the network makes of the probability are the inputs to a sigmoid centered at zero (1 / (1 + e^-x)), so they vary from around -6 to +6.
|
|
5
|
+
The pixels greater than the cellprob_threshold are used to run dynamics and determine ROIs.
|
|
6
|
+
The default is cellprob_threshold=0.0.
|
|
7
|
+
Decrease this threshold if cellpose is not returning as many ROIs as you’d expect.
|
|
8
|
+
Similarly, increase this threshold if cellpose is returning too ROIs particularly from dim areas.
|
|
9
|
+
""" #Cellpose 4.0.6 doc
|
|
10
|
+
|
|
11
|
+
FLOW_THRESHOLD_TOOLTIP = """ (float) from 0. to 1.
|
|
12
|
+
The flow_threshold parameter is the maximum allowed error of the flows for each mask.
|
|
13
|
+
Increase this threshold if cellpose is not returning as many ROIs as you’d expect.
|
|
14
|
+
Similarly, decrease this threshold if cellpose is returning too many ill-shaped ROIs.
|
|
15
|
+
""" #Cellpose 4.0.6 doc
|
small_fish_gui/hints.py
CHANGED
|
@@ -9,9 +9,16 @@ class pipeline_parameters(TypedDict) :
|
|
|
9
9
|
At run time is a regular dict instance, this class is used for keys hinting
|
|
10
10
|
"""
|
|
11
11
|
alpha : float
|
|
12
|
+
anisotropy : float
|
|
12
13
|
beta : float
|
|
13
14
|
channel_to_compute : int
|
|
15
|
+
cellprob_threshold_cyto : float
|
|
16
|
+
cellprob_threshold_nuc : float
|
|
17
|
+
cytoplasm_segmentation_3D : bool
|
|
14
18
|
cluster_size : int
|
|
19
|
+
cyto_model_name : str
|
|
20
|
+
cytoplasm_diameter : int
|
|
21
|
+
cytoplasm_channel : int
|
|
15
22
|
do_cluster_computation : bool
|
|
16
23
|
do_dense_regions_deconvolution : bool
|
|
17
24
|
do_spots_excel : bool
|
|
@@ -19,10 +26,11 @@ class pipeline_parameters(TypedDict) :
|
|
|
19
26
|
do_spots_csv : bool
|
|
20
27
|
dim : int
|
|
21
28
|
filename : str
|
|
29
|
+
flow_threshold_cyto : int
|
|
30
|
+
flow_threshold_nuc : int
|
|
22
31
|
gamma : float
|
|
23
32
|
image_path : str
|
|
24
33
|
image : ndarray
|
|
25
|
-
show_interactive_threshold_selector : bool
|
|
26
34
|
log_kernel_size : Tuple[float,float,float]
|
|
27
35
|
log_kernel_size_x : float
|
|
28
36
|
log_kernel_size_y : float
|
|
@@ -34,18 +42,29 @@ class pipeline_parameters(TypedDict) :
|
|
|
34
42
|
minimum_distance_z : float
|
|
35
43
|
is_3D_stack : bool
|
|
36
44
|
is_multichannel : bool
|
|
37
|
-
show_napari_corrector : bool
|
|
38
45
|
nucleus_channel_signal : int
|
|
39
|
-
|
|
46
|
+
nucleus_segmentation_3D : bool
|
|
47
|
+
nucleus_diameter : int
|
|
48
|
+
nucleus_model_name : str
|
|
49
|
+
nucleus_channel : int
|
|
50
|
+
other_nucleus_image : str
|
|
51
|
+
reordered_shape : Tuple[int,int,int,int,int]
|
|
40
52
|
do_segmentation : bool
|
|
41
|
-
segmentation_done : bool
|
|
42
53
|
shape : Tuple[int,int,int,int,int]
|
|
54
|
+
save_segmentation_visual : bool
|
|
55
|
+
segmentation_done : bool
|
|
56
|
+
show_interactive_threshold_selector : bool
|
|
43
57
|
spots_extraction_folder : str
|
|
44
58
|
spots_filename : str
|
|
45
59
|
spot_size : Tuple[int,int,int]
|
|
46
60
|
spot_size_x : int
|
|
47
61
|
spot_size_y : int
|
|
48
62
|
spot_size_z : int
|
|
63
|
+
segment_only_nuclei : bool
|
|
64
|
+
cytoplasm_segmentation_3D : bool
|
|
65
|
+
nucleus_segmentation_3D : bool
|
|
66
|
+
show_napari_corrector : bool
|
|
67
|
+
show_segmentation : bool
|
|
49
68
|
threshold : int
|
|
50
69
|
threshold_penalty : int
|
|
51
70
|
time_stack : None
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
small_fish_gui/logo.png
ADDED
|
Binary file
|
|
@@ -7,31 +7,33 @@ from small_fish_gui import __version__
|
|
|
7
7
|
import pandas as pd
|
|
8
8
|
import FreeSimpleGUI as sg
|
|
9
9
|
|
|
10
|
-
from .actions import add_detection
|
|
11
|
-
from .
|
|
12
|
-
from .
|
|
13
|
-
from .
|
|
14
|
-
from .
|
|
15
|
-
from .actions import open_wiki
|
|
16
|
-
|
|
17
|
-
from ._preprocess import clean_unused_parameters_cache
|
|
18
|
-
from
|
|
19
|
-
from
|
|
20
|
-
from
|
|
10
|
+
from .pipeline.actions import add_detection
|
|
11
|
+
from .pipeline.actions import save_results
|
|
12
|
+
from .pipeline.actions import compute_colocalisation
|
|
13
|
+
from .pipeline.actions import delete_acquisitions, rename_acquisitions
|
|
14
|
+
from .pipeline.actions import save_segmentation, load_segmentation, segment_cells
|
|
15
|
+
from .pipeline.actions import open_wiki
|
|
16
|
+
|
|
17
|
+
from .pipeline._preprocess import clean_unused_parameters_cache
|
|
18
|
+
from .batch import batch_promp
|
|
19
|
+
from .gui import hub_prompt, prompt_restore_main_menu, default_theme
|
|
20
|
+
from .hints import pipeline_parameters
|
|
21
21
|
|
|
22
22
|
#'Global' parameters
|
|
23
23
|
user_parameters = pipeline_parameters({'segmentation_done' : False}) #TypedDict
|
|
24
24
|
acquisition_id = -1
|
|
25
|
-
result_df = pd.DataFrame(columns=['acquisition_id'])
|
|
25
|
+
result_df = pd.DataFrame(columns=['acquisition_id', 'name'])
|
|
26
26
|
cell_result_df = pd.DataFrame(columns=['acquisition_id'])
|
|
27
27
|
global_coloc_df = pd.DataFrame()
|
|
28
28
|
cell_coloc_df = dict()
|
|
29
29
|
cytoplasm_label = None
|
|
30
30
|
nucleus_label = None
|
|
31
31
|
|
|
32
|
+
default_theme()
|
|
32
33
|
while True : #Break this loop to close small_fish
|
|
33
34
|
try :
|
|
34
35
|
result_df = result_df.reset_index(drop=True)
|
|
36
|
+
|
|
35
37
|
event, values = hub_prompt(result_df, user_parameters['segmentation_done'])
|
|
36
38
|
|
|
37
39
|
if event == 'Add detection' :
|
|
@@ -71,14 +73,13 @@ while True : #Break this loop to close small_fish
|
|
|
71
73
|
nucleus_label, cytoplasm_label, user_parameters['segmentation_done'] = load_segmentation(nucleus_label, cytoplasm_label, user_parameters['segmentation_done'])
|
|
72
74
|
|
|
73
75
|
elif event == 'Compute colocalisation' :
|
|
74
|
-
result_tables = values.setdefault('result_table', []) #Contains the lines selected by the user on the sum-up array.
|
|
75
76
|
|
|
76
|
-
global_coloc_df, cell_coloc_df = compute_colocalisation(
|
|
77
|
-
result_tables,
|
|
77
|
+
global_coloc_df, cell_coloc_df, acquisition_id = compute_colocalisation(
|
|
78
78
|
result_dataframe=result_df,
|
|
79
79
|
cell_result_dataframe=cell_result_df,
|
|
80
80
|
global_coloc_df=global_coloc_df,
|
|
81
81
|
cell_coloc_df=cell_coloc_df,
|
|
82
|
+
max_id=acquisition_id,
|
|
82
83
|
)
|
|
83
84
|
|
|
84
85
|
elif event == "Reset all" :
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from ._custom_errors import MissMatchError
|
|
2
2
|
from ..gui import coloc_prompt, add_default_loading
|
|
3
3
|
|
|
4
|
+
import os
|
|
4
5
|
import numpy as np
|
|
5
6
|
import pandas as pd
|
|
6
7
|
import FreeSimpleGUI as sg
|
|
@@ -116,7 +117,12 @@ def spots_multicolocalisation(spots_list, anchor_list, radius_nm, image_shape, v
|
|
|
116
117
|
|
|
117
118
|
return res
|
|
118
119
|
|
|
119
|
-
def spots_colocalisation(
|
|
120
|
+
def spots_colocalisation(
|
|
121
|
+
spot_list1:np.ndarray,
|
|
122
|
+
spot_list2:np.ndarray,
|
|
123
|
+
distance: int,
|
|
124
|
+
voxel_size : tuple
|
|
125
|
+
)-> int :
|
|
120
126
|
"""
|
|
121
127
|
Return number of spots from spot_list1 located closer(large) than distance to at least one spot of spot_list2.
|
|
122
128
|
|
|
@@ -133,9 +139,15 @@ def spots_colocalisation(spot_list1:list, spot_list2:list, distance: float, voxe
|
|
|
133
139
|
if len(spot_list1) == 0 or len(spot_list2) == 0 : return np.NaN
|
|
134
140
|
if len(spot_list1[0]) != len(spot_list2[0]) :
|
|
135
141
|
raise MissMatchError("dimensionalities of spots 1 and spots 2 don't match.")
|
|
136
|
-
|
|
142
|
+
|
|
143
|
+
spot_list1 = np.array([spot for spot in spot_list1], dtype=int)
|
|
144
|
+
spot_list2 = np.array([spot for spot in spot_list2], dtype=int)
|
|
145
|
+
|
|
137
146
|
shape1 = np.max(spot_list1,axis=0)
|
|
138
147
|
shape2 = np.max(spot_list2,axis=0)
|
|
148
|
+
|
|
149
|
+
Z,Y,X = list(zip(*spot_list2))
|
|
150
|
+
|
|
139
151
|
image_shape = np.max([shape1, shape2],axis=0) + 1
|
|
140
152
|
|
|
141
153
|
signal2 = reconstruct_boolean_signal(image_shape, spot_list2)
|
|
@@ -152,25 +164,48 @@ def spots_colocalisation(spot_list1:list, spot_list2:list, distance: float, voxe
|
|
|
152
164
|
return count
|
|
153
165
|
|
|
154
166
|
|
|
155
|
-
|
|
167
|
+
def initiate_colocalisation(
|
|
168
|
+
result_tables : pd.DataFrame,
|
|
169
|
+
) :
|
|
156
170
|
|
|
171
|
+
result_tables = result_tables.set_index('acquisition_id', drop=False)
|
|
172
|
+
available_spots = dict(zip(result_tables['acquisition_id'].astype(str).str.cat(result_tables['name'],sep='-'), result_tables.index))
|
|
157
173
|
|
|
174
|
+
while True :
|
|
175
|
+
try :
|
|
176
|
+
colocalisation_distance, voxel_size, spots1_key, spots2_key = coloc_prompt(list(available_spots.keys()))
|
|
177
|
+
if colocalisation_distance is None :
|
|
178
|
+
return None,None, None,None
|
|
179
|
+
colocalisation_distance = int(colocalisation_distance)
|
|
158
180
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
181
|
+
if spots1_key in available_spots.keys() :
|
|
182
|
+
spots1_key = available_spots[spots1_key]
|
|
183
|
+
elif os.path.isfile(spots1_key) :
|
|
184
|
+
pass
|
|
185
|
+
|
|
186
|
+
else :
|
|
187
|
+
raise ValueError("Incorrect value for spots1")
|
|
188
|
+
|
|
189
|
+
if spots2_key in available_spots.keys() :
|
|
190
|
+
spots2_key = available_spots[spots2_key]
|
|
191
|
+
elif os.path.isfile(spots2_key) :
|
|
192
|
+
pass
|
|
171
193
|
else :
|
|
172
|
-
|
|
173
|
-
|
|
194
|
+
raise ValueError("Incorrect value for spots1")
|
|
195
|
+
|
|
196
|
+
except ValueError as e :
|
|
197
|
+
|
|
198
|
+
if str(e) == "Incorrect value for spots1" :
|
|
199
|
+
sg.popup(str(e))
|
|
200
|
+
|
|
201
|
+
elif str(e) == "Incorrect value for spots2" :
|
|
202
|
+
sg.popup(str(e))
|
|
203
|
+
|
|
204
|
+
else :
|
|
205
|
+
sg.popup("Incorrect colocalisation distance")
|
|
206
|
+
else :
|
|
207
|
+
break
|
|
208
|
+
return colocalisation_distance, voxel_size, spots1_key, spots2_key
|
|
174
209
|
|
|
175
210
|
def _global_coloc(acquisition_id1,acquisition_id2, result_dataframe, colocalisation_distance) :
|
|
176
211
|
"""
|
|
@@ -198,20 +233,12 @@ def _global_coloc(acquisition_id1,acquisition_id2, result_dataframe, colocalisat
|
|
|
198
233
|
|
|
199
234
|
voxel_size1 = acquisition1.iloc[0].at['voxel_size']
|
|
200
235
|
voxel_size2 = acquisition2.iloc[0].at['voxel_size']
|
|
201
|
-
shape1 = acquisition1.iloc[0].at['reordered_shape']
|
|
202
|
-
shape2 = acquisition2.iloc[0].at['reordered_shape']
|
|
203
236
|
|
|
204
237
|
if voxel_size1 != voxel_size2 :
|
|
205
238
|
raise MissMatchError("voxel size 1 different than voxel size 2")
|
|
206
239
|
else :
|
|
207
240
|
voxel_size = voxel_size1
|
|
208
241
|
|
|
209
|
-
if shape1 != shape2 :
|
|
210
|
-
raise MissMatchError("shape 1 different than shape 2")
|
|
211
|
-
else :
|
|
212
|
-
shape = shape1
|
|
213
|
-
|
|
214
|
-
|
|
215
242
|
spots1 = acquisition1.iloc[0].at['spots']
|
|
216
243
|
spots2 = acquisition2.iloc[0].at['spots']
|
|
217
244
|
|
|
@@ -228,7 +255,7 @@ def _global_coloc(acquisition_id1,acquisition_id2, result_dataframe, colocalisat
|
|
|
228
255
|
|
|
229
256
|
if 'clusters' in acquisition1.columns :
|
|
230
257
|
try :
|
|
231
|
-
clusters_id_1 = acquisition1.iloc[0].at['spots_cluster_id']
|
|
258
|
+
clusters_id_1 = np.array(acquisition1.iloc[0].at['spots_cluster_id'], dtype=int)
|
|
232
259
|
fraction_spots2_coloc_cluster1 = spots_colocalisation(spot_list1=spots2, spot_list2=spots1[clusters_id_1 != -1], distance= colocalisation_distance, voxel_size=voxel_size) / spot2_total
|
|
233
260
|
except MissMatchError as e :
|
|
234
261
|
sg.popup(str(e))
|
|
@@ -241,7 +268,7 @@ def _global_coloc(acquisition_id1,acquisition_id2, result_dataframe, colocalisat
|
|
|
241
268
|
|
|
242
269
|
if 'clusters' in acquisition2.columns :
|
|
243
270
|
try :
|
|
244
|
-
clusters_id_2 = acquisition2.iloc[0].at['spots_cluster_id']
|
|
271
|
+
clusters_id_2 = np.array(acquisition2.iloc[0].at['spots_cluster_id'], dtype=int)
|
|
245
272
|
fraction_spots1_coloc_cluster2 = spots_colocalisation(spot_list1=spots1, spot_list2=spots2[clusters_id_2 != -1], distance= colocalisation_distance, voxel_size=voxel_size) / spot1_total
|
|
246
273
|
except MissMatchError as e :# clusters not computed
|
|
247
274
|
sg.popup(str(e))
|
|
@@ -314,10 +341,6 @@ def _cell_coloc(
|
|
|
314
341
|
coloc_name_forward = '{0} -> {1}'.format(acquisition_name_id1, acquisition_name_id2)
|
|
315
342
|
coloc_name_backward = '{1} -> {0}'.format(acquisition_name_id1, acquisition_name_id2)
|
|
316
343
|
|
|
317
|
-
#Getting shape
|
|
318
|
-
if not result_dataframe.at[acquisition_id1, 'reordered_shape'] == result_dataframe.at[acquisition_id2, 'reordered_shape'] :
|
|
319
|
-
raise ValueError("Selected acquisitions have different shapes. Most likely they don't belong to the same fov.")
|
|
320
|
-
|
|
321
344
|
#Getting voxel_size
|
|
322
345
|
if not result_dataframe.at[acquisition_id1, 'voxel_size'] == result_dataframe.at[acquisition_id2, 'voxel_size'] :
|
|
323
346
|
raise ValueError("Selected acquisitions have different voxel_size. Most likely they don't belong to the same fov.")
|
|
@@ -328,9 +351,9 @@ def _cell_coloc(
|
|
|
328
351
|
|
|
329
352
|
#Putting spots lists in 2 cols for corresponding cells
|
|
330
353
|
pivot_values_columns = ['rna_coords', 'total_rna_number']
|
|
331
|
-
if 'clusters' in acquisition2.columns or 'clusters' in acquisition1.columns
|
|
354
|
+
if 'clusters' in acquisition2.columns or 'clusters' in acquisition1.columns:
|
|
332
355
|
pivot_values_columns.extend(['clustered_spots_coords','clustered_spot_number'])
|
|
333
|
-
cell_dataframe['cell_id'] = cell_dataframe['cell_id'].astype(int)
|
|
356
|
+
cell_dataframe.loc[:,['cell_id']] = cell_dataframe['cell_id'].astype(int)
|
|
334
357
|
colocalisation_df = cell_dataframe.pivot(
|
|
335
358
|
columns=['name', 'acquisition_id'],
|
|
336
359
|
values= pivot_values_columns,
|
|
@@ -357,7 +380,7 @@ def _cell_coloc(
|
|
|
357
380
|
)
|
|
358
381
|
colocalisation_df[("spots_with_spots_fraction",coloc_name_backward,"backward")] = colocalisation_df[("spots_with_spots_count",coloc_name_backward,"backward")].astype(float) / colocalisation_df[('total_rna_number',acquisition_name_id2,acquisition_id2)].astype(float)
|
|
359
382
|
|
|
360
|
-
if
|
|
383
|
+
if 'clusters' in acquisition2.columns:
|
|
361
384
|
if len(acquisition2['clusters'].iat[0]) > 0 :
|
|
362
385
|
|
|
363
386
|
#spots to clusters
|
|
@@ -371,7 +394,7 @@ def _cell_coloc(
|
|
|
371
394
|
)
|
|
372
395
|
colocalisation_df[("spots_with_clustered_spots_fraction",coloc_name_forward,"forward")] = colocalisation_df[("spots_with_clustered_spots_count",coloc_name_forward,"forward")].astype(float) / colocalisation_df[('total_rna_number',acquisition_name_id1,acquisition_id1)].astype(float)
|
|
373
396
|
|
|
374
|
-
if
|
|
397
|
+
if 'clusters' in acquisition1.columns:
|
|
375
398
|
if len(acquisition1['clusters'].iat[0]) > 0 :
|
|
376
399
|
colocalisation_df[("spots_with_clustered_spots_count",coloc_name_backward,"backward")] = colocalisation_df.apply(
|
|
377
400
|
lambda x: spots_colocalisation(
|
|
@@ -384,7 +407,7 @@ def _cell_coloc(
|
|
|
384
407
|
|
|
385
408
|
colocalisation_df[("spots_with_clustered_spots_fraction",coloc_name_backward,"backward")] = colocalisation_df[("spots_with_clustered_spots_count",coloc_name_backward,"backward")].astype(float) / colocalisation_df[('total_rna_number',acquisition_name_id2,acquisition_id2)].astype(float)
|
|
386
409
|
|
|
387
|
-
if
|
|
410
|
+
if 'clusters' in acquisition2.columns and 'clusters' in acquisition1.columns:
|
|
388
411
|
if len(acquisition1['clusters'].iat[0]) > 0 and len(acquisition2['clusters'].iat[0]) > 0 :
|
|
389
412
|
#clusters to clusters
|
|
390
413
|
colocalisation_df[("clustered_spots_with_clustered_spots_count",coloc_name_forward,"forward")] = colocalisation_df.apply(
|
|
@@ -420,12 +443,8 @@ def _cell_coloc(
|
|
|
420
443
|
return colocalisation_df
|
|
421
444
|
|
|
422
445
|
@add_default_loading
|
|
423
|
-
def launch_colocalisation(
|
|
446
|
+
def launch_colocalisation(acquisition_id1, acquisition_id2, result_dataframe, cell_result_dataframe, colocalisation_distance, global_coloc_df, cell_coloc_df: dict) :
|
|
424
447
|
|
|
425
|
-
acquisition1 = result_dataframe.iloc[result_tables[0]]
|
|
426
|
-
acquisition2 = result_dataframe.iloc[result_tables[1]]
|
|
427
|
-
|
|
428
|
-
acquisition_id1, acquisition_id2 = (acquisition1.at['acquisition_id'], acquisition2.at['acquisition_id'])
|
|
429
448
|
|
|
430
449
|
if acquisition_id1 in list(cell_result_dataframe['acquisition_id']) and acquisition_id2 in list(cell_result_dataframe['acquisition_id']) :
|
|
431
450
|
print("Launching cell to cell colocalisation.")
|
|
@@ -4,6 +4,8 @@ import FreeSimpleGUI as sg
|
|
|
4
4
|
from ..gui import _error_popup, _warning_popup, parameters_layout, add_header
|
|
5
5
|
from ..gui.prompts import input_image_prompt, prompt
|
|
6
6
|
|
|
7
|
+
import small_fish_gui.default_values as default
|
|
8
|
+
|
|
7
9
|
class ParameterInputError(Exception) :
|
|
8
10
|
"""
|
|
9
11
|
Raised when user inputs an incorrect parameter.
|
|
@@ -314,19 +316,19 @@ def _check_segmentation_parameters(
|
|
|
314
316
|
) :
|
|
315
317
|
|
|
316
318
|
available_channels = list(range(len(shape)))
|
|
317
|
-
do_only_nuc = user_parameters['
|
|
319
|
+
do_only_nuc = user_parameters['segment_only_nuclei']
|
|
318
320
|
cyto_model_name = user_parameters['cyto_model_name']
|
|
319
|
-
cyto_size = user_parameters['
|
|
320
|
-
cytoplasm_channel = user_parameters['
|
|
321
|
+
cyto_size = user_parameters['cytoplasm_diameter']
|
|
322
|
+
cytoplasm_channel = user_parameters['cytoplasm_channel']
|
|
321
323
|
nucleus_model_name = user_parameters['nucleus_model_name']
|
|
322
|
-
nucleus_size = user_parameters['
|
|
323
|
-
nucleus_channel = user_parameters['
|
|
324
|
+
nucleus_size = user_parameters['nucleus_diameter']
|
|
325
|
+
nucleus_channel = user_parameters['nucleus_channel']
|
|
324
326
|
|
|
325
327
|
|
|
326
328
|
if type(cyto_model_name) != str and not do_only_nuc:
|
|
327
329
|
raise ParameterInputError('Invalid cytoplasm model name.')
|
|
328
330
|
if cytoplasm_channel not in available_channels and not do_only_nuc and is_multichannel:
|
|
329
|
-
raise ParameterInputError('For given input image please select channel in {0}\
|
|
331
|
+
raise ParameterInputError('For given input image please select channel in {0}\ncytoplasm_channel : {1}'.format(available_channels, cytoplasm_channel))
|
|
330
332
|
|
|
331
333
|
if type(cyto_size) not in [int, float] and not do_only_nuc:
|
|
332
334
|
raise ParameterInputError("Incorrect cytoplasm size.")
|
|
@@ -361,12 +363,11 @@ def ask_input_parameters(ask_for_segmentation=True) :
|
|
|
361
363
|
values = {}
|
|
362
364
|
image_input_values = {}
|
|
363
365
|
while True :
|
|
364
|
-
is_3D_preset = image_input_values.setdefault('is_3D_stack',
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
do_napari_preset = image_input_values.setdefault('show_napari_corrector', False)
|
|
366
|
+
is_3D_preset = image_input_values.setdefault('is_3D_stack', default.IS_3D_STACK)
|
|
367
|
+
is_multichannel_preset = image_input_values.setdefault('is_multichannel', default.IS_MULTICHANNEL)
|
|
368
|
+
denseregion_preset = image_input_values.setdefault('do_dense_regions_deconvolution', default.DO_DENSE_REGIONS_DECONVOLUTION)
|
|
369
|
+
do_clustering_preset = image_input_values.setdefault('do_cluster_computation', default.DO_CLUSTER_COMPUTATION)
|
|
370
|
+
do_napari_preset = image_input_values.setdefault('show_napari_corrector', default.SHOW_NAPARI_CORRECTOR)
|
|
370
371
|
|
|
371
372
|
if ask_for_segmentation :
|
|
372
373
|
image_input_values = input_image_prompt(
|
|
@@ -17,6 +17,7 @@ from ._preprocess import ask_input_parameters
|
|
|
17
17
|
from .detection import initiate_detection, launch_detection, launch_features_computation
|
|
18
18
|
from .detection import get_nucleus_signal
|
|
19
19
|
from .spots import launch_spots_extraction
|
|
20
|
+
from .spots import load_spots, reconstruct_acquisition_data, reconstruct_cell_data
|
|
20
21
|
|
|
21
22
|
from .segmentation import launch_segmentation
|
|
22
23
|
from ._colocalisation import initiate_colocalisation, launch_colocalisation
|
|
@@ -115,7 +116,7 @@ def add_detection(user_parameters : pipeline_parameters, acquisition_id, cytopla
|
|
|
115
116
|
|
|
116
117
|
if user_parameters['spots_extraction_folder'] != '' and type(user_parameters['spots_extraction_folder']) != type(None) :
|
|
117
118
|
if user_parameters['spots_filename'] != '' and type(user_parameters['spots_filename']) != type(None) :
|
|
118
|
-
if any(
|
|
119
|
+
if any([user_parameters['do_spots_excel'], user_parameters['do_spots_csv']]) :
|
|
119
120
|
launch_spots_extraction(
|
|
120
121
|
acquisition_id=acquisition_id,
|
|
121
122
|
user_parameters=user_parameters,
|
|
@@ -242,9 +243,11 @@ def save_results(
|
|
|
242
243
|
global_coloc_df : pd.DataFrame,
|
|
243
244
|
cell_coloc_df : dict, #TODO : Rename to cell_coloc_dict
|
|
244
245
|
) :
|
|
245
|
-
if len(result_df) != 0
|
|
246
|
+
if len(result_df) != 0 :
|
|
246
247
|
dic = output_image_prompt(filename=result_df.iloc[0].at['filename'])
|
|
247
248
|
|
|
249
|
+
if dic is None : return None
|
|
250
|
+
|
|
248
251
|
if isinstance(dic, dict) :
|
|
249
252
|
path = dic['folder']
|
|
250
253
|
filename = dic['filename']
|
|
@@ -260,26 +263,111 @@ def save_results(
|
|
|
260
263
|
sucess4 = write_list_of_results(cell_coloc_df.values(), path= path, filename=filename + 'cell2cell_coloc_result', do_excel= do_excel, do_feather= do_feather, do_csv=do_csv)
|
|
261
264
|
if all([sucess1,sucess2, sucess3, sucess4,]) : sg.popup("Sucessfully saved at {0}.".format(path))
|
|
262
265
|
|
|
266
|
+
elif len(global_coloc_df) !=0 or len(cell_coloc_df) !=0 :
|
|
267
|
+
dic = output_image_prompt(filename="loaded_spots_coloc")
|
|
268
|
+
if dic is None : return None
|
|
269
|
+
if isinstance(dic, dict) :
|
|
270
|
+
path = dic['folder']
|
|
271
|
+
filename = dic['filename']
|
|
272
|
+
do_excel = dic['Excel']
|
|
273
|
+
do_feather = dic['Feather']
|
|
274
|
+
do_csv = dic['csv']
|
|
275
|
+
|
|
276
|
+
if 'rna_coords' in cell_result_df.columns : cell_result_df = cell_result_df.drop(columns='rna_coords')
|
|
277
|
+
|
|
278
|
+
sucess3 = write_results(global_coloc_df, path= path, filename=filename + 'global_coloc_result', do_excel= do_excel, do_feather= do_feather, do_csv=do_csv)
|
|
279
|
+
sucess4 = write_list_of_results(cell_coloc_df.values(), path= path, filename=filename + 'cell2cell_coloc_result', do_excel= do_excel, do_feather= do_feather, do_csv=do_csv)
|
|
280
|
+
if all([sucess3, sucess4,]) : sg.popup("Sucessfully saved at {0}.".format(path))
|
|
281
|
+
|
|
282
|
+
|
|
263
283
|
else :
|
|
264
284
|
dic = None
|
|
265
285
|
sg.popup('No results to save.')
|
|
266
286
|
|
|
267
|
-
def compute_colocalisation(
|
|
268
|
-
|
|
287
|
+
def compute_colocalisation(
|
|
288
|
+
result_dataframe,
|
|
289
|
+
cell_result_dataframe,
|
|
290
|
+
global_coloc_df,
|
|
291
|
+
cell_coloc_df,
|
|
292
|
+
max_id,
|
|
293
|
+
) :
|
|
294
|
+
|
|
295
|
+
colocalisation_distance, voxel_size, spots1_key, spots2_key = initiate_colocalisation(result_dataframe)
|
|
296
|
+
if colocalisation_distance is None :
|
|
297
|
+
return global_coloc_df, cell_coloc_df, max_id
|
|
298
|
+
|
|
299
|
+
if os.path.isfile(spots1_key) :
|
|
300
|
+
Spots1 = load_spots(spots1_key)
|
|
301
|
+
fake_acquisition = reconstruct_acquisition_data(
|
|
302
|
+
Spots=Spots1,
|
|
303
|
+
max_id=max_id,
|
|
304
|
+
filename= os.path.basename(spots1_key),
|
|
305
|
+
voxel_size = voxel_size
|
|
306
|
+
)
|
|
307
|
+
result_dataframe = pd.concat([
|
|
308
|
+
result_dataframe,
|
|
309
|
+
fake_acquisition
|
|
310
|
+
], axis=0)
|
|
311
|
+
|
|
312
|
+
if not Spots1['cell_label'].isna().all() :
|
|
313
|
+
fake_cells = reconstruct_cell_data(
|
|
314
|
+
Spots=Spots1,
|
|
315
|
+
max_id=max_id,
|
|
316
|
+
)
|
|
317
|
+
|
|
318
|
+
cell_result_dataframe = pd.concat([
|
|
319
|
+
cell_result_dataframe,
|
|
320
|
+
fake_cells
|
|
321
|
+
], axis=0)
|
|
322
|
+
|
|
323
|
+
max_id +=1
|
|
324
|
+
acquisition_id1 = fake_acquisition.iloc[0].at['acquisition_id']
|
|
269
325
|
|
|
270
|
-
if colocalisation_distance == False :
|
|
271
|
-
pass
|
|
272
326
|
else :
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
327
|
+
acquisition_id1 = spots1_key
|
|
328
|
+
|
|
329
|
+
if os.path.isfile(spots2_key) :
|
|
330
|
+
Spots2 = load_spots(spots2_key)
|
|
331
|
+
fake_acquisition = reconstruct_acquisition_data(
|
|
332
|
+
Spots=Spots2,
|
|
333
|
+
max_id=max_id,
|
|
334
|
+
filename= os.path.basename(spots2_key),
|
|
335
|
+
voxel_size = voxel_size
|
|
336
|
+
)
|
|
337
|
+
result_dataframe = pd.concat([
|
|
338
|
+
result_dataframe,
|
|
339
|
+
fake_acquisition
|
|
340
|
+
], axis=0)
|
|
341
|
+
|
|
342
|
+
if not Spots2['cell_label'].isna().all() :
|
|
343
|
+
fake_cells = reconstruct_cell_data(
|
|
344
|
+
Spots=Spots2,
|
|
345
|
+
max_id=max_id,
|
|
280
346
|
)
|
|
281
347
|
|
|
282
|
-
|
|
348
|
+
cell_result_dataframe = pd.concat([
|
|
349
|
+
cell_result_dataframe,
|
|
350
|
+
fake_cells
|
|
351
|
+
], axis=0)
|
|
352
|
+
|
|
353
|
+
max_id +=1
|
|
354
|
+
acquisition_id2 = fake_acquisition.iloc[0].at['acquisition_id']
|
|
355
|
+
|
|
356
|
+
else :
|
|
357
|
+
acquisition_id2 = spots2_key
|
|
358
|
+
|
|
359
|
+
|
|
360
|
+
global_coloc_df, cell_coloc_df = launch_colocalisation(
|
|
361
|
+
acquisition_id1 = acquisition_id1,
|
|
362
|
+
acquisition_id2 = acquisition_id2,
|
|
363
|
+
result_dataframe=result_dataframe,
|
|
364
|
+
cell_result_dataframe=cell_result_dataframe,
|
|
365
|
+
colocalisation_distance=colocalisation_distance,
|
|
366
|
+
global_coloc_df=global_coloc_df,
|
|
367
|
+
cell_coloc_df=cell_coloc_df,
|
|
368
|
+
)
|
|
369
|
+
|
|
370
|
+
return global_coloc_df, cell_coloc_df, max_id
|
|
283
371
|
|
|
284
372
|
def delete_acquisitions(selected_acquisitions : pd.DataFrame,
|
|
285
373
|
result_df : pd.DataFrame,
|
|
@@ -443,7 +443,11 @@ def launch_cell_extraction(
|
|
|
443
443
|
image = stack.maximum_projection(image)
|
|
444
444
|
if nucleus_signal.ndim == 3 :
|
|
445
445
|
nucleus_signal = stack.maximum_projection(nucleus_signal)
|
|
446
|
-
|
|
446
|
+
if cell_label.ndim == 3 :
|
|
447
|
+
cell_label = stack.maximum_projection(nucleus_signal)
|
|
448
|
+
if nucleus_label.ndim == 3 :
|
|
449
|
+
nucleus_label = stack.maximum_projection(nucleus_signal)
|
|
450
|
+
|
|
447
451
|
cells_results = multistack.extract_cell(
|
|
448
452
|
cell_label=cell_label,
|
|
449
453
|
ndim=dim,
|