small-fish-gui 1.7.1__py3-none-any.whl → 1.8.1__py3-none-any.whl

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