small-fish-gui 1.9.2__py3-none-any.whl → 1.9.4__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 CHANGED
@@ -5,7 +5,7 @@ Cell segmentation (**2D**) is peformed using *cellpose* (published work) : https
5
5
 
6
6
  Spot detection is performed via *big-fish* (published work) : https://github.com/fish-quant/big-fish
7
7
 
8
- **Time stacks are not supported.**
8
+ ***Small Fish is bulding a [wiki](https://github.com/2Echoes/small_fish_gui/wiki) ! Make sure to check it out.***
9
9
 
10
10
  ## What can you do with small fish ?
11
11
 
@@ -93,5 +93,12 @@ Note that for training it is recommended to first set up your GPU as training co
93
93
  ## Developpement
94
94
 
95
95
  Optional features to include in future versions :
96
- - time stack (which would include cell tracking)
97
- - 3D segmentation
96
+
97
+ **Major Dev**
98
+ * time stack (which would include cell tracking)
99
+ * 3D segmentation
100
+
101
+ **Minor features**
102
+ * allows npz files with multiple masks in load segmentation by asking user which one to select
103
+ * fix parquet format or replace to another compressed format
104
+ * In Napari viewer, or add an extra spot layer to visualsize spots that are in foci or color spots that are in clusters in specific color.
@@ -36,6 +36,5 @@ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
36
36
  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37
37
  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
38
38
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39
-
40
39
  """
41
- __version__ = "1.9.2"
40
+ __version__ = "1.9.4"
@@ -1,20 +1,32 @@
1
- import sys, subprocess
2
- import PySimpleGUI as sg
3
-
1
+ import sys, subprocess, traceback, os, re
4
2
  from small_fish_gui import __version__
5
3
 
6
4
  def main():
7
5
  import small_fish_gui.pipeline.main
8
6
 
9
- def is_last_version() :
10
- latest_version = str(subprocess.run([sys.executable, '-m', 'pip', 'install', '{}==random'.format('small_fish_gui')], capture_output=True, text=True))
11
- latest_version = latest_version[latest_version.find('(from versions:')+15:]
12
- latest_version = latest_version[:latest_version.find(')')]
13
- latest_version = latest_version.replace(' ','').split(',')[-1]
7
+ def _get_version() :
8
+ return __version__
14
9
 
15
- current_version = __version__
10
+ AVAILABLE_ARGUMENTS = {
11
+ ('-v','--v','--version') : "Prompt the software version.",
12
+ ('--launch', '-l') : "Launch small fish gui, equivalent to no arguments.",
13
+ ('-h', '--help', '--h') : "Prompt this help menu."
14
+ }
16
15
 
17
- return current_version == latest_version
16
+ def is_last_version() :
17
+
18
+ query = subprocess.run([sys.executable, '-m', 'pip', 'index', 'versions', 'small_fish_gui'], capture_output=True, text=True)
19
+ all_version = query.stdout.split(',')
20
+ latest_version = all_version[0]
21
+ regex = r"\d+\.\d+\.\d+"
22
+ latest = re.findall(regex, latest_version)
23
+
24
+ current_version = _get_version()
25
+
26
+ if len(latest) == 0 :
27
+ return current_version
28
+ else :
29
+ return current_version == latest[-1]
18
30
 
19
31
  if __name__ == "__main__":
20
32
 
@@ -22,8 +34,29 @@ if __name__ == "__main__":
22
34
  print("A new version of Small Fish is available. To update close small fish and type :\npip install --upgrade small_fish_gui")
23
35
 
24
36
  try :
37
+ arguments = sys.argv
38
+
39
+ if len(arguments) > 1 :
40
+ if arguments[1] in ['-v','--v','--version'] :
41
+ print(_get_version())
42
+ quit()
43
+ elif arguments[1] in ['--launch', '-l'] :
44
+ pass
45
+ elif arguments[1] in ['-h', '--help', '--h'] :
46
+ for key, help in AVAILABLE_ARGUMENTS.items() :
47
+ print(f"{key} : {help}")
48
+ quit()
49
+ else :
50
+ print(f"Incorrect argument : {arguments}, to launch small fish don't pass any argument or pick amongst {AVAILABLE_ARGUMENTS.keys()}")
51
+
25
52
  sys.exit(main())
53
+
26
54
  except Exception as error :
27
- sg.popup("Sorry. Something went wrong...\nIf you have some time to spare could you please communicate the error you encountered (next window) on :\nhttps://github.com/2Echoes/small_fish/issues.")
28
- sg.popup_error_with_traceback(error)
29
- raise error
55
+ with open("error_log.txt",'a') as error_log :
56
+ error_log.writelines([
57
+ f"version {_get_version()}",
58
+ f"error : {error}",
59
+ f"traceback :\n{traceback.format_exc()}",
60
+ ])
61
+
62
+ print(f"error_log saved at {os.getcwd()}/error_log.txt. Please consider reporting this by opening an issue on github.")
@@ -6,7 +6,7 @@ import os
6
6
  import czifile as czi
7
7
  import bigfish.stack as stack
8
8
  import numpy as np
9
- import PySimpleGUI as sg
9
+ import FreeSimpleGUI as sg
10
10
 
11
11
  from ..pipeline._preprocess import check_integrity, convert_parameters_types, ParameterInputError, _check_segmentation_parameters
12
12
  from ..pipeline.segmentation import _cast_segmentation_parameters
@@ -4,7 +4,7 @@ Submodule keeping necessary calls from main pipeline for batch processing.
4
4
 
5
5
  import os
6
6
  import pandas as pd
7
- import PySimpleGUI as sg
7
+ import FreeSimpleGUI as sg
8
8
 
9
9
  from ..hints import pipeline_parameters
10
10
 
@@ -57,172 +57,198 @@ def batch_pipeline(
57
57
  window_print(batch_window,"Launching batch analysis...")
58
58
  batch_progress_bar.update(max=len(filenames_list))
59
59
  filenames_list.sort()
60
+
61
+
62
+ error_log = open(main_dir + "error_log", mode='w')
63
+ error_count = 0
64
+
60
65
  for acquisition_id, file in enumerate(filenames_list) :
61
-
62
- #GUI
63
- window_print(batch_window,"\nNext file : {0}".format(file))
64
- batch_progress_bar.update(current_count= acquisition_id, max= len(filenames_list))
65
- progress_count.update(value=str(acquisition_id))
66
- batch_window = batch_window.refresh()
67
-
68
- #0. Open image
69
- image = open_image(input_path + '/' + file)
70
- parameters['image'] = image
71
- parameters['filename'] = file
72
- for key_to_clean in [0,2] :
73
- if key_to_clean in parameters : del parameters[key_to_clean]
74
-
75
- #1. Re-order shape
76
- shape = image.shape
77
- parameters['shape'] = shape
78
- parameters['reordered_shape'] = reorder_shape(shape, map_=map_)
79
-
80
- #2. Segmentation (opt)
81
- if do_segmentation :
82
- window_print(batch_window,"Segmenting cells...")
83
- im_seg = reorder_image_stack(map_, image)
84
- parameters = _cast_segmentation_parameters(parameters)
85
- cytoplasm_label, nucleus_label = cell_segmentation(
86
- im_seg,
87
- cyto_model_name= parameters['cyto_model_name'],
88
- cyto_diameter= parameters['cytoplasm diameter'],
89
- nucleus_model_name= parameters['nucleus_model_name'],
90
- nucleus_diameter= parameters['nucleus diameter'],
91
- channels=[parameters['cytoplasm channel'], parameters['nucleus channel']],
92
- do_only_nuc=parameters['Segment only nuclei']
93
- )
94
-
95
- parameters['segmentation_done'] = True
96
-
97
- if cytoplasm_label.max() == 0 : #No cell segmented
98
- window_print(batch_window,"No cell was segmented, computing next image.")
99
- continue
100
- else :
101
- window_print(batch_window, "{0} cells segmented.".format(cytoplasm_label.max()))
102
-
103
- if parameters['save segmentation'] :
104
- plot_segmentation(
105
- cyto_image=im_seg[parameters['cytoplasm channel']],
106
- cyto_label= cytoplasm_label,
107
- nuc_image= im_seg[parameters['nucleus channel']],
108
- nuc_label=nucleus_label,
109
- path= main_dir + "segmentation/" + file,
110
- do_only_nuc= parameters['Segment only nuclei'],
66
+ try :
67
+
68
+ #GUI
69
+ window_print(batch_window,"\nNext file : {0}".format(file))
70
+ batch_progress_bar.update(current_count= acquisition_id, max= len(filenames_list))
71
+ progress_count.update(value=str(acquisition_id))
72
+ batch_window = batch_window.refresh()
73
+
74
+ #0. Open image
75
+ image = open_image(input_path + '/' + file)
76
+ parameters['image'] = image
77
+ parameters['filename'] = file
78
+ for key_to_clean in [0,2] :
79
+ if key_to_clean in parameters : del parameters[key_to_clean]
80
+
81
+ #1. Re-order shape
82
+ shape = image.shape
83
+ parameters['shape'] = shape
84
+ parameters['reordered_shape'] = reorder_shape(shape, map_=map_)
85
+
86
+ #2. Segmentation (opt)
87
+ if do_segmentation :
88
+ window_print(batch_window,"Segmenting cells...")
89
+ im_seg = reorder_image_stack(map_, image)
90
+ parameters = _cast_segmentation_parameters(parameters)
91
+ cytoplasm_label, nucleus_label = cell_segmentation(
92
+ im_seg,
93
+ cyto_model_name= parameters['cyto_model_name'],
94
+ cyto_diameter= parameters['cytoplasm diameter'],
95
+ nucleus_model_name= parameters['nucleus_model_name'],
96
+ nucleus_diameter= parameters['nucleus diameter'],
97
+ channels=[parameters['cytoplasm channel'], parameters['nucleus channel']],
98
+ do_only_nuc=parameters['Segment only nuclei']
111
99
  )
112
100
 
113
- else :
114
- cytoplasm_label, nucleus_label = None,None
115
- parameters['segmentation_done'] = False
116
-
117
- #3. Detection, deconvolution, clusterisation
118
- window_print(batch_window,"Detecting spots...")
119
- parameters = convert_parameters_types(parameters)
120
- image, other_image = prepare_image_detection(map_, parameters)
121
- nucleus_signal = get_nucleus_signal(image, other_image, parameters)
122
- try : # Catch error raised if user enter a spot size too small compare to voxel size
123
- parameters, frame_result, spots, clusters, spot_cluster_id = launch_detection(
124
- image,
125
- other_image,
126
- parameters,
127
- cell_label=cytoplasm_label,
128
- nucleus_label=nucleus_label,
129
- hide_loading=True,
130
- )
101
+ parameters['segmentation_done'] = True
102
+
103
+ if cytoplasm_label.max() == 0 : #No cell segmented
104
+ window_print(batch_window,"No cell was segmented, computing next image.")
105
+ continue
106
+ else :
107
+ window_print(batch_window, "{0} cells segmented.".format(cytoplasm_label.max()))
108
+
109
+ if parameters['save segmentation'] :
110
+ plot_segmentation(
111
+ cyto_image=im_seg[parameters['cytoplasm channel']],
112
+ cyto_label= cytoplasm_label,
113
+ nuc_image= im_seg[parameters['nucleus channel']],
114
+ nuc_label=nucleus_label,
115
+ path= main_dir + "segmentation/" + file,
116
+ do_only_nuc= parameters['Segment only nuclei'],
117
+ )
131
118
 
132
- except ValueError as error :
133
- if "The array should have an upper bound of 1" in str(error) :
134
- window_print(batch_window,"Spot size too small for current voxel size.")
135
- continue
136
119
  else :
137
- raise(error)
138
-
139
- if parameters['save detection'] :
140
- if parameters['do_cluster_computation'] :
141
- if len(clusters) > 0 :
142
- spots_list = [spots, clusters[:,:-2]]
143
- else : spots_list = [spots]
144
- else : spots_list = [spots]
145
- output_spot_tiffvisual(
146
- image,
147
- spots_list= spots_list,
148
- dot_size=2,
149
- path_output= main_dir + "detection/" + file + "_spot_detection.tiff"
150
- )
120
+ cytoplasm_label, nucleus_label = None,None
121
+ parameters['segmentation_done'] = False
122
+
123
+ #3. Detection, deconvolution, clusterisation
124
+ window_print(batch_window,"Detecting spots...")
125
+ parameters = convert_parameters_types(parameters)
126
+ image, other_image = prepare_image_detection(map_, parameters)
127
+ nucleus_signal = get_nucleus_signal(image, other_image, parameters)
128
+ try : # Catch error raised if user enter a spot size too small compare to voxel size
129
+ parameters, frame_result, spots, clusters, spot_cluster_id = launch_detection(
130
+ image,
131
+ other_image,
132
+ parameters,
133
+ cell_label=cytoplasm_label,
134
+ nucleus_label=nucleus_label,
135
+ hide_loading=True,
136
+ )
151
137
 
152
- #4. Spots extraction
153
- window_print(batch_window,"Extracting spots : ")
154
- if parameters['extract spots'] :
155
-
156
- #Setting parameter for call to lauch spot extraction
157
- #Only spots have one file per image to avoir memory overload
158
- parameters['do_spots_excel'] = parameters['xlsx']
159
- parameters['do_spots_csv'] = parameters['csv']
160
- parameters['do_spots_feather'] = parameters['feather']
161
- parameters['spots_filename'] = "spots_extractions_{0}".format(file)
162
- parameters['spots_extraction_folder'] = main_dir + "results/spots_extraction/"
163
-
164
- launch_spots_extraction(
165
- acquisition_id=acquisition_id + last_acquisition_id,
166
- user_parameters=parameters,
167
- image=image,
168
- spots=spots,
169
- cluster_id=spot_cluster_id,
170
- nucleus_label= nucleus_label,
171
- cell_label= cytoplasm_label,
138
+ except ValueError as error :
139
+ if "The array should have an upper bound of 1" in str(error) :
140
+ window_print(batch_window,"Spot size too small for current voxel size.")
141
+ continue
142
+ else :
143
+ raise(error)
144
+
145
+ if parameters['save detection'] :
146
+ if parameters['do_cluster_computation'] :
147
+ if len(clusters) > 0 :
148
+ spots_list = [spots, clusters[:,:-2]]
149
+ else : spots_list = [spots]
150
+ else : spots_list = [spots]
151
+ output_spot_tiffvisual(
152
+ image,
153
+ spots_list= spots_list,
154
+ dot_size=2,
155
+ path_output= main_dir + "detection/" + file + "_spot_detection.tiff"
172
156
  )
173
157
 
174
- #5. Features computation
175
- window_print(batch_window,"computing features...")
176
- new_results_df, new_cell_results_df = launch_features_computation(
177
- acquisition_id=acquisition_id + last_acquisition_id,
178
- image=image,
179
- nucleus_signal = nucleus_signal,
180
- spots=spots,
181
- clusters=clusters,
182
- spots_cluster_id=spot_cluster_id,
183
- nucleus_label = nucleus_label,
184
- cell_label= cytoplasm_label,
185
- user_parameters=parameters,
186
- frame_results=frame_result,
187
- )
188
-
189
- results_df = pd.concat([
190
- results_df.reset_index(drop=True), new_results_df.reset_index(drop=True)
191
- ], axis=0)
192
-
193
- cell_results_df = pd.concat([
194
- cell_results_df.reset_index(drop=True), new_cell_results_df.reset_index(drop=True)
195
- ], axis=0)
196
-
197
-
198
- #6. Saving results
199
- window_print(batch_window,"saving image_results...")
200
- #1 file per batch + 1 file per batch if segmentation
201
- acquisition_success = write_results(
202
- results_df,
203
- path= main_dir + "results/",
204
- filename=batch_name,
205
- do_excel= parameters["xlsx"],
206
- do_feather= parameters["feather"],
207
- do_csv= parameters["csv"],
208
- overwrite=True,
158
+ #4. Spots extraction
159
+ window_print(batch_window,"Extracting spots : ")
160
+ if parameters['extract spots'] :
161
+
162
+ #Setting parameter for call to lauch spot extraction
163
+ #Only spots have one file per image to avoir memory overload
164
+ parameters['do_spots_excel'] = parameters['xlsx']
165
+ parameters['do_spots_csv'] = parameters['csv']
166
+ parameters['do_spots_feather'] = parameters['feather']
167
+ parameters['spots_filename'] = "spots_extractions_{0}".format(file)
168
+ parameters['spots_extraction_folder'] = main_dir + "results/spots_extraction/"
169
+
170
+ launch_spots_extraction(
171
+ acquisition_id=acquisition_id + last_acquisition_id,
172
+ user_parameters=parameters,
173
+ image=image,
174
+ spots=spots,
175
+ cluster_id=spot_cluster_id,
176
+ nucleus_label= nucleus_label,
177
+ cell_label= cytoplasm_label,
178
+ )
179
+
180
+ #5. Features computation
181
+ window_print(batch_window,"computing features...")
182
+ new_results_df, new_cell_results_df = launch_features_computation(
183
+ acquisition_id=acquisition_id + last_acquisition_id,
184
+ image=image,
185
+ nucleus_signal = nucleus_signal,
186
+ spots=spots,
187
+ clusters=clusters,
188
+ spots_cluster_id=spot_cluster_id,
189
+ nucleus_label = nucleus_label,
190
+ cell_label= cytoplasm_label,
191
+ user_parameters=parameters,
192
+ frame_results=frame_result,
209
193
  )
210
-
211
- if do_segmentation :
212
- cell_success = write_results(
213
- cell_results_df,
194
+
195
+ results_df = pd.concat([
196
+ results_df.reset_index(drop=True), new_results_df.reset_index(drop=True)
197
+ ], axis=0)
198
+
199
+ cell_results_df = pd.concat([
200
+ cell_results_df.reset_index(drop=True), new_cell_results_df.reset_index(drop=True)
201
+ ], axis=0)
202
+
203
+
204
+ #6. Saving results
205
+ window_print(batch_window,"saving image_results...")
206
+ #1 file per batch + 1 file per batch if segmentation
207
+ acquisition_success = write_results(
208
+ results_df,
214
209
  path= main_dir + "results/",
215
- filename=batch_name + '_cell_result',
210
+ filename=batch_name,
216
211
  do_excel= parameters["xlsx"],
217
212
  do_feather= parameters["feather"],
218
213
  do_csv= parameters["csv"],
219
214
  overwrite=True,
220
215
  )
221
-
222
- window_print(batch_window,"Sucessfully saved.")
223
216
 
217
+ if do_segmentation :
218
+ cell_success = write_results(
219
+ cell_results_df,
220
+ path= main_dir + "results/",
221
+ filename=batch_name + '_cell_result',
222
+ do_excel= parameters["xlsx"],
223
+ do_feather= parameters["feather"],
224
+ do_csv= parameters["csv"],
225
+ overwrite=True,
226
+ )
227
+
228
+ window_print(batch_window,"Sucessfully saved.")
229
+
230
+ except Exception as error :
231
+
232
+ error_count +=1
233
+ print("Exception raised for acquisition, writting error in error log.")
234
+
235
+ log = [
236
+ f"Error raised during acquisition {acquisition_id}.\n"
237
+ ]
238
+ log.append(str(error) + '\n')
239
+
240
+ error_log.writelines(log)
241
+
242
+ print("Ignoring current acquisition and proceeding to next one.")
243
+ continue
244
+
245
+
224
246
 
225
247
  batch_progress_bar.update(current_count= acquisition_id+1, max= len(filenames_list))
226
248
  progress_count.update(value=str(acquisition_id+1))
227
249
  batch_window = batch_window.refresh()
250
+
251
+ if error_count > 0 :
252
+ sg.popup(f"Batch processing finished but {error_count} acquisitions were skipped during quantification.\nFor more informations check error_log in result folder.")
253
+
228
254
  return results_df, cell_results_df, acquisition_id
@@ -3,7 +3,7 @@ Submodule with main function to call to launch batch mode.
3
3
  """
4
4
 
5
5
  import os
6
- import PySimpleGUI as sg
6
+ import FreeSimpleGUI as sg
7
7
 
8
8
  from .utils import get_elmt_from_key, create_map, call_auto_map
9
9
  from .pipeline import batch_pipeline
@@ -1,4 +1,4 @@
1
- import PySimpleGUI as sg
1
+ import FreeSimpleGUI as sg
2
2
  import small_fish_gui.batch as batch
3
3
  import pandas as pd
4
4
 
@@ -1,7 +1,7 @@
1
1
  """
2
2
  Functions handling GUI update while user is interacting with software.
3
3
  """
4
- import PySimpleGUI as sg
4
+ import FreeSimpleGUI as sg
5
5
 
6
6
  from .utils import get_elmt_from_key
7
7
 
@@ -1,4 +1,4 @@
1
- import PySimpleGUI as sg
1
+ import FreeSimpleGUI as sg
2
2
  from ..pipeline._preprocess import _auto_map_channels
3
3
  from ..pipeline._preprocess import MappingError
4
4
 
@@ -15,6 +15,7 @@ from .prompts import ask_cancel_detection
15
15
  from .prompts import ask_cancel_segmentation
16
16
  from .prompts import ask_help
17
17
  from .prompts import ask_detection_confirmation
18
+ from .prompts import prompt_restore_main_menu
18
19
 
19
20
  #Helpers to build windows
20
21
  from .layout import parameters_layout
@@ -1,4 +1,4 @@
1
- import PySimpleGUI as sg
1
+ import FreeSimpleGUI as sg
2
2
  import numpy as np
3
3
 
4
4
  WAITING_TEXT = [
@@ -1,4 +1,4 @@
1
- import PySimpleGUI as sg
1
+ import FreeSimpleGUI as sg
2
2
  import os
3
3
 
4
4
 
@@ -1,4 +1,4 @@
1
- import PySimpleGUI as sg
1
+ import FreeSimpleGUI as sg
2
2
  import os
3
3
  from ..utils import check_parameter
4
4
  import cellpose.models as models
@@ -198,7 +198,7 @@ def correct_spots(
198
198
  if len(clusters) > 0 :
199
199
  clusters_coordinates = clusters[:, :dim]
200
200
  else :
201
- clusters_coordinates = np.empty(shape=(0,3), dtype=int)
201
+ clusters_coordinates = np.empty(shape=(0,dim), dtype=int)
202
202
  Viewer.add_points( # cluster; this layer can be update by user.
203
203
  clusters_coordinates,
204
204
  size = 10,
@@ -222,8 +222,8 @@ def correct_spots(
222
222
  if type(clusters) != type(None) :
223
223
  new_clusters = np.round(Viewer.layers['foci'].data).astype(int)
224
224
  if len(new_clusters) == 0 :
225
- new_clusters = np.empty(shape=(0,5), dtype=int)
226
- new_cluster_id = -1 * np.ones(len(new_spots))
225
+ new_clusters = np.empty(shape=(0,dim + 2), dtype=int)
226
+ new_cluster_id = -1 * np.ones(shape=(len(new_spots), 1), dtype=int)
227
227
  new_spots = np.concatenate([new_spots, new_cluster_id], axis=1)
228
228
  else :
229
229
  new_cluster_id = Viewer.layers['foci'].features.to_numpy()
@@ -1,4 +1,4 @@
1
- import PySimpleGUI as sg
1
+ import FreeSimpleGUI as sg
2
2
  import pandas as pd
3
3
  import os
4
4
  import numpy as np
@@ -222,7 +222,6 @@ def detection_parameters_promt(
222
222
  else : values['dim'] = 2
223
223
  return values
224
224
 
225
-
226
225
  def ask_replace_file(filename:str) :
227
226
  layout = [
228
227
  [sg.Text("{0} already exists, replace ?")],
@@ -341,7 +340,6 @@ def ask_cancel_detection() :
341
340
  else :
342
341
  return True
343
342
 
344
-
345
343
  def ask_confirmation(question_displayed : str) :
346
344
  layout =[
347
345
  [sg.Text(question_displayed, font= 'bold 10')],
@@ -355,7 +353,6 @@ def ask_confirmation(question_displayed : str) :
355
353
  else :
356
354
  return True
357
355
 
358
-
359
356
  def prompt_save_segmentation() -> 'dict[Literal["folder","filename","ext"]]':
360
357
  while True :
361
358
  relaunch = False
@@ -406,4 +403,29 @@ def prompt_load_segmentation() -> 'dict[Literal["nucleus","cytoplasm"]]':
406
403
  if not relaunch : break
407
404
 
408
405
 
409
- return values
406
+ return values
407
+
408
+ def prompt_restore_main_menu() -> bool :
409
+ """
410
+ Warn user that software will try to go back to main menu while saving parameters, and propose to save results and quit if stuck.
411
+
412
+ Returns True if user want to save and quit else False, to raise error close window.
413
+ """
414
+
415
+
416
+ layout = [
417
+ [sg.Text("An error was caught while proceeding.\nSoftware can try to save parameters and return to main menu or save results and quit.")],
418
+ [sg.Button("Return to main menu", key='menu'), sg.Button("Save and quit", key='save')]
419
+ ]
420
+
421
+ window = sg.Window('small fish', layout=layout, margins=(10,10), auto_size_text=True, resizable=True)
422
+ event, values = window.read(close=True)
423
+
424
+ if event is None :
425
+ return None
426
+ elif event == "save" :
427
+ return True
428
+ elif event == "menu" :
429
+ return False
430
+ else :
431
+ raise AssertionError("Unforseen answer")
@@ -4,7 +4,7 @@ import numpy as np
4
4
  from bigfish.stack import check_parameter
5
5
  from typing import Literal
6
6
 
7
- MAX_LEN_EXCEL = 1048576
7
+ MAX_LEN_EXCEL = 1048576 #Maximum number of lines that can be written in an excel file
8
8
 
9
9
  def _cast_spot_to_tuple(spot) :
10
10
  return tuple([coord for coord in spot])
@@ -120,10 +120,21 @@ def input_segmentation(
120
120
  nucleus_path : str,
121
121
  cytoplasm_path : str,
122
122
  ) :
123
- nucleus_label = np.load(nucleus_path)
123
+
124
+ if nucleus_path.endswith('.npy') or nucleus_path.endswith('.npz') :
125
+ nucleus_label = np.load(nucleus_path)
126
+ else :
127
+ raise ValueError("Wrong extension for mask file, only npy and npz are supported")
128
+
124
129
 
125
130
  if cytoplasm_path != '' :
126
- cytoplasm_label = np.load(cytoplasm_path)
131
+
132
+ if cytoplasm_path.endswith('.npy') or cytoplasm_path.endswith('.npz') :
133
+ cytoplasm_label = np.load(cytoplasm_path)
134
+ else :
135
+ raise ValueError("Wrong extension for mask file, only npy and npz are supported")
136
+
137
+
127
138
  else :
128
139
  cytoplasm_label = nucleus_label
129
140
 
@@ -1,4 +1,4 @@
1
- import PySimpleGUI as sg
1
+ import FreeSimpleGUI as sg
2
2
 
3
3
  layout = [
4
4
  [sg.Radio(['A',], key='button', group_id=0, key='test1'),sg.Radio(['B'], key='button', group_id=0, key='test2'), sg.Radio(['C'], key='button', group_id=0, key='test3')],
@@ -3,7 +3,7 @@ from ..gui import coloc_prompt, add_default_loading
3
3
 
4
4
  import numpy as np
5
5
  import pandas as pd
6
- import PySimpleGUI as sg
6
+ import FreeSimpleGUI as sg
7
7
  from scipy.ndimage import distance_transform_edt
8
8
  from scipy.signal import fftconvolve
9
9
 
@@ -413,7 +413,8 @@ def _cell_coloc(
413
413
  colocalisation_df = colocalisation_df.drop('rna_coords', axis=1)
414
414
  colocalisation_df['voxel_size'] = [voxel_size]*len(colocalisation_df)
415
415
  colocalisation_df['pair_name'] = [(acquisition_name_id1, acquisition_name_id2)] * len(colocalisation_df)
416
- colocalisation_df['pair_acquisition_id'] = [(acquisition_id1, acquisition_id2)] * len(colocalisation_df)
416
+ colocalisation_df['acquisition_id_1'] = [acquisition_id1] * len(colocalisation_df)
417
+ colocalisation_df['acquisition_id_2'] = [acquisition_id2] * len(colocalisation_df)
417
418
  colocalisation_df['colocalisation_distance'] = colocalisation_distance
418
419
 
419
420
  return colocalisation_df
@@ -1,6 +1,6 @@
1
1
  import numpy as np
2
2
  import os
3
- import PySimpleGUI as sg
3
+ import FreeSimpleGUI as sg
4
4
  from ..gui import _error_popup, _warning_popup, parameters_layout, add_header, prompt, prompt_with_help
5
5
  from ..gui.prompts import input_image_prompt
6
6
 
@@ -25,7 +25,7 @@ from ..hints import pipeline_parameters
25
25
 
26
26
  import os
27
27
  import pandas as pd
28
- import PySimpleGUI as sg
28
+ import FreeSimpleGUI as sg
29
29
  import numpy as np
30
30
 
31
31
  def segment_cells(user_parameters : pipeline_parameters, nucleus_label, cytoplasm_label) :
@@ -76,6 +76,7 @@ def add_detection(user_parameters : pipeline_parameters, acquisition_id, cytopla
76
76
  if type(detection_parameters) != type(None) :
77
77
  user_parameters.update(detection_parameters)
78
78
  else : #If user clicks cancel
79
+
79
80
  cancel = ask_cancel_detection()
80
81
  if cancel :
81
82
  return new_results_df, new_cell_results_df, acquisition_id, user_parameters
@@ -201,13 +202,22 @@ def load_segmentation(nucleus_label, cytoplasm_label, segmentation_done) :
201
202
  else :
202
203
  return nucleus_label, cytoplasm_label, segmentation_done
203
204
 
204
- answer = prompt_load_segmentation()
205
- if type(answer) == type(None) : #user clicks cancel
206
- return nucleus_label, cytoplasm_label, segmentation_done
207
- nucleus_label, cytoplasm_label = input_segmentation(
208
- answer['nucleus'],
209
- answer['cytoplasm'],
210
- )
205
+ while True :
206
+ answer = prompt_load_segmentation()
207
+
208
+ if type(answer) == type(None) : #user clicks cancel
209
+ return nucleus_label, cytoplasm_label, segmentation_done
210
+
211
+ try :
212
+ nucleus_label, cytoplasm_label = input_segmentation(
213
+ answer['nucleus'],
214
+ answer['cytoplasm'],
215
+ )
216
+
217
+ except ValueError as e :
218
+ sg.popup(str(e))
219
+ else :
220
+ break
211
221
 
212
222
  if type(nucleus_label) != type(None) and type(nucleus_label) != np.ndarray :
213
223
  nucleus_label = nucleus_label['arr_0']
@@ -19,7 +19,7 @@ from napari.types import LayerDataTuple
19
19
 
20
20
  import numpy as np
21
21
  import pandas as pd
22
- import PySimpleGUI as sg
22
+ import FreeSimpleGUI as sg
23
23
  from numpy import NaN
24
24
  import bigfish.detection as detection
25
25
  import bigfish.stack as stack
@@ -220,7 +220,7 @@ def initiate_detection(user_parameters : pipeline_parameters, map_, shape) :
220
220
  segmentation_done= user_parameters['segmentation_done'],
221
221
  default_dict=detection_parameters
222
222
  )
223
- if type(detection_parameters) == type(None) : return user_parameters
223
+ if type(detection_parameters) == type(None) : return None
224
224
  try :
225
225
  detection_parameters = convert_parameters_types(detection_parameters)
226
226
  detection_parameters = check_integrity(
@@ -710,7 +710,14 @@ def launch_features_computation(
710
710
  if user_parameters['segmentation_done'] :
711
711
  cell_result_dframe['name'] = name
712
712
  cell_result_dframe = cell_result_dframe.loc[:,['name'] + cell_result_col]
713
- cell_result_dframe['total_rna_number'] = cell_result_dframe['nb_rna_in_nuc'] + cell_result_dframe['nb_rna_out_nuc']
713
+ if 'nb_rna_in_nuc' in cell_result_dframe.columns and 'nb_rna_out_nuc' in cell_result_dframe.columns :
714
+ cell_result_dframe['total_rna_number'] = cell_result_dframe['nb_rna_in_nuc'] + cell_result_dframe['nb_rna_out_nuc']
715
+ else : # This can happen when segmentation is performed and detects cells but they are on fov edges and thus removed by big-fish.
716
+ print("\033[1;31m All segmented cells where skipped because they are found on fov edges (incomplete cells), if you want to analyse this image check segmentation.\033[00m")
717
+ cell_result_dframe['nb_rna_in_nuc'] = np.NaN
718
+ cell_result_dframe['nb_rna_out_nuc'] = np.NaN
719
+ cell_result_dframe['total_rna_number'] = np.NaN
720
+
714
721
 
715
722
  return frame_results, cell_result_dframe
716
723
 
@@ -2,9 +2,10 @@
2
2
  This script is called when software starts; it is the main loop.
3
3
  """
4
4
 
5
+ import traceback
5
6
  import pandas as pd
6
- import PySimpleGUI as sg
7
- from ..gui import hub_prompt
7
+ import FreeSimpleGUI as sg
8
+ from ..gui import hub_prompt, prompt_restore_main_menu
8
9
  from .actions import add_detection, save_results, compute_colocalisation, delete_acquisitions, rename_acquisitions, save_segmentation, load_segmentation, segment_cells
9
10
  from ._preprocess import clean_unused_parameters_cache
10
11
  from ..batch import batch_promp
@@ -109,5 +110,21 @@ while True : #Break this loop to close small_fish
109
110
 
110
111
  except Exception as error :
111
112
  sg.popup(str(error))
112
- raise error
113
+
114
+ save_quit = prompt_restore_main_menu()
115
+
116
+ if save_quit is None :
117
+ raise error
118
+
119
+ elif save_quit :
120
+ save_results(
121
+ result_df=result_df,
122
+ cell_result_df=cell_result_df,
123
+ global_coloc_df=global_coloc_df,
124
+ cell_coloc_df = cell_coloc_df,
125
+ )
126
+ quit()
127
+ else :
128
+ continue
129
+
113
130
  quit()
@@ -20,7 +20,7 @@ import numpy as np
20
20
  import bigfish.multistack as multistack
21
21
  import bigfish.stack as stack
22
22
  import bigfish.plot as plot
23
- import PySimpleGUI as sg
23
+ import FreeSimpleGUI as sg
24
24
  import matplotlib.pyplot as plt
25
25
  import os
26
26
 
@@ -2045,7 +2045,7 @@
2045
2045
  ],
2046
2046
  "metadata": {
2047
2047
  "kernelspec": {
2048
- "display_name": "cellpose",
2048
+ "display_name": "small_fish",
2049
2049
  "language": "python",
2050
2050
  "name": "python3"
2051
2051
  },
@@ -2059,7 +2059,7 @@
2059
2059
  "name": "python",
2060
2060
  "nbconvert_exporter": "python",
2061
2061
  "pygments_lexer": "ipython3",
2062
- "version": "3.8.16"
2062
+ "version": "3.8.19"
2063
2063
  }
2064
2064
  },
2065
2065
  "nbformat": 4,
@@ -9,7 +9,7 @@ napari-plugin-manager==0.1.0a2
9
9
  napari-svg==0.1.10
10
10
  numpy==1.24.4
11
11
  pandas==1.5.3
12
- PySimpleGUI==4.60.5
12
+ FreeSimpleGUI==5.1.1
13
13
  scipy==1.9.1
14
14
  scikit-image==0.19.1
15
15
  scikit-learn==1.3.2
@@ -1,8 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: small_fish_gui
3
- Version: 1.9.2
3
+ Version: 1.9.4
4
4
  Summary: Small Fish is a python application for the analysis of smFish images. It provides a ready to use graphical interface to combine famous python packages for cell analysis without any need for coding.
5
5
  Project-URL: Homepage, https://github.com/2Echoes/small_fish
6
+ Project-URL: Wiki, https://github.com/2Echoes/small_fish_gui/wiki
6
7
  Project-URL: Issues, https://github.com/2Echoes/small_fish/issues
7
8
  Author-email: Slimani Floric <floric.slimani@live.com>
8
9
  License-File: LICENSE
@@ -13,6 +14,7 @@ Requires-Python: >=3.8
13
14
  Requires-Dist: big-fish==0.6.2
14
15
  Requires-Dist: cellpose==3.0.7
15
16
  Requires-Dist: czifile==2019.7.2
17
+ Requires-Dist: freesimplegui==5.1.1
16
18
  Requires-Dist: imageio==2.34.0
17
19
  Requires-Dist: napari-console==0.0.9
18
20
  Requires-Dist: napari-plugin-engine==0.2.0
@@ -23,7 +25,6 @@ Requires-Dist: numpy==1.24.4
23
25
  Requires-Dist: openpyxl==3.1.2
24
26
  Requires-Dist: pandas==1.5.3
25
27
  Requires-Dist: pyarrow==11.0.0
26
- Requires-Dist: pysimplegui==4.60.5
27
28
  Requires-Dist: scikit-image==0.19.1
28
29
  Requires-Dist: scikit-learn==1.3.2
29
30
  Requires-Dist: scipy==1.9.1
@@ -0,0 +1,51 @@
1
+ small_fish_gui/LICENSE,sha256=-iFy8VGBYs5VsHglKpk4D-hxqQ2jMJaqmfq_ulIzDks,1303
2
+ small_fish_gui/README.md,sha256=rhcqAWtQWPEmheUzChY_ok-ytAkZlboNQHdx19LRutw,4643
3
+ small_fish_gui/Segmentation example.jpg,sha256=opfiSbjmfF6z8kBs08sg_FNR2Om0AcMPU5sSwSLHdoQ,215038
4
+ small_fish_gui/__init__.py,sha256=WGaTzQTK6LJ7mTFtO3En_DlnGCBHIf8HLnam2jRXKjk,1940
5
+ small_fish_gui/__main__.py,sha256=ngHNZr9ui8FTE9FPUJ9ULFGMs-5Wenpbcq__wAwFOAI,2128
6
+ small_fish_gui/hints.py,sha256=_AhC-Th36ELxinjMyGtjIqJfZkISPr1YwhQ9ifD9Kj4,1926
7
+ small_fish_gui/napari_detection_example.png,sha256=l5EZlrbXemLiGqb5inSVsD6Kko1Opz528-go-fBfrw8,977350
8
+ small_fish_gui/requirements.txt,sha256=z8iaxqarErZuMpmRKqcW07nfb_tQAOOkQ4LQSA9ovCk,322
9
+ small_fish_gui/utils.py,sha256=LM6QW2ono_LIRv7JXIIq7ZxxbDXqBtZ5uR9gjKJfwM8,1903
10
+ small_fish_gui/.github/workflows/python-publish.yml,sha256=5Ltnuhw9TevhzndlBmdUgYMnS73xEAxSyd1u8DHdn5s,1084
11
+ small_fish_gui/batch/__init__.py,sha256=ku2_Yate-UG89Q0BmE2B9kFV4kOz-u9Lf2lj6VsdFXs,127
12
+ small_fish_gui/batch/input.py,sha256=mqnP8LBhyNbtlcqjVlUiVeuHw4YxOX3GgzJbq03isKE,1477
13
+ small_fish_gui/batch/integrity.py,sha256=qyttOwsukds6eE2j6NRmA8-fQtHxlnP4tgwQqrs3EWs,4853
14
+ small_fish_gui/batch/pipeline.py,sha256=-XSyGTrk7WYhgLZLZeUoJvyzfcoprJTofUuIz623Irw,10419
15
+ small_fish_gui/batch/prompt.py,sha256=OOwCn8TvAFIIm3fjhOfMwZkvXHk8fDgxefN_FO3p-5s,18851
16
+ small_fish_gui/batch/test.py,sha256=FcoCngSeueociwVoG8V3C6lQO7rrRHUfIVA2hJKr4v4,213
17
+ small_fish_gui/batch/update.py,sha256=uVenjjJBHZ3MeW5b20HzlSBueu3QZWEGLIEHRnPm-Tg,5044
18
+ small_fish_gui/batch/utils.py,sha256=Pnmzlen8gmLBYBthMiUiK0TErjBBSId9SjKeBd9U6-U,1784
19
+ small_fish_gui/batch/values.txt,sha256=eS19O1pdj0HYfwGUlWIpkvfNZQFxA3F4BDR8qahXh28,999
20
+ small_fish_gui/gui/__init__.py,sha256=-t93Mz9AkpZsTH3XdYGj5-CXJNbWJ62k40QTWgpAGQA,913
21
+ small_fish_gui/gui/_napari_widgets.py,sha256=8IMppaPZU37ANdZwTZOhwqCEly0hokzYL7UIVIixGns,3022
22
+ small_fish_gui/gui/animation.py,sha256=MnYsA1kxQZ72L_H0knxOs41lG0ZZv1re7gSgYNmZY00,983
23
+ small_fish_gui/gui/help_module.py,sha256=_6ZTiCym1uYJTlKekPSmGCXQVr6z7TRaxEhRAL90Eko,9614
24
+ small_fish_gui/gui/layout.py,sha256=ew5d3Mlr0DnC3j3uCWBzykEHJ8faa4wmKHZbiNOjdJY,14188
25
+ small_fish_gui/gui/napari_visualiser.py,sha256=AmpUErfko1ZamYoORRsgR4JT9xRzQKpi-sFok-FFKtg,14569
26
+ small_fish_gui/gui/prompts.py,sha256=Kqqhb3DJujHE3NNWMZKMTBQ7h1B79GicvdnaG4i3HG4,16301
27
+ small_fish_gui/gui/testing.ipynb,sha256=5xoMDR2a3aa4q8KoEoJ22HrcWDyHkCF4arVeVVm7ovs,71500
28
+ small_fish_gui/gui/screenshot/general_help_screenshot.png,sha256=X4E6Td5f04K-pBUPDaBJRAE3D5b8fuEdiAUKhkIDr-0,54210
29
+ small_fish_gui/gui/screenshot/mapping_help_screenshot.png,sha256=HcuRh5TYciUogUasza5vZ_QSshaiHsskQK23mh9vQS8,34735
30
+ small_fish_gui/gui/screenshot/segmentation_help_screenshot.png,sha256=rbSgIydT0gZtfMh1qk4mdMbEIyCaakvHmxa2eOrLwO0,118944
31
+ small_fish_gui/interface/__init__.py,sha256=_yCOvJjrMGVeGx9Lkyqp7t3fAztt67w2ZKLPj8_kfYc,277
32
+ small_fish_gui/interface/image.py,sha256=VBSfIVcR50aJxxbD_ILflPX4esW9lXPArfHpVQynzCc,1100
33
+ small_fish_gui/interface/inoutput.py,sha256=FXKSSRrVou5VBWvTbiBjSCr7DncIyZbcV5MfRa6J64g,5467
34
+ small_fish_gui/interface/testing.py,sha256=5GHjGn3YVJxfXGolMeg4SSCTBgPGl5R5bxQrpmsZ1yg,399
35
+ small_fish_gui/pipeline/__init__.py,sha256=Oww6dcuvnktl5jFKLriz8ZXObKo9MkneE739A8C1reY,739
36
+ small_fish_gui/pipeline/_colocalisation.py,sha256=PJ9IkICwPiaTNRTX4xqPhf1J3wyE2yAFRPtYEbw2k-A,21298
37
+ small_fish_gui/pipeline/_custom_errors.py,sha256=tQ-AUhgzIFpK30AZiQQrtHCHyGVRDdAoIjzL0Fk-1pA,43
38
+ small_fish_gui/pipeline/_preprocess.py,sha256=f8TSoieM8PXgEVemnOa1zW8LrfXdE9ZZ61kXcM4HOrk,15091
39
+ small_fish_gui/pipeline/_signaltonoise.py,sha256=7A9t7xu7zghI6cr201Ldm-LjJ5NOuP56VSeJ8KIzcUo,8497
40
+ small_fish_gui/pipeline/actions.py,sha256=YLuRoVwG0bdQ3LvwQDrObQZaHzsOMlntrayfxY13OCw,15941
41
+ small_fish_gui/pipeline/detection.py,sha256=Pe_1e8FKqvVyhuDOPdb2LmDKpuvS7Vg1IXWX83HqTz4,35556
42
+ small_fish_gui/pipeline/main.py,sha256=X8xyTXxNIgK25LO7X29BpIglR5zwEHh8fpyaROLD7HE,5260
43
+ small_fish_gui/pipeline/segmentation.py,sha256=8oZVs6EF0cE89OfauR_sxpzf9uxtqjAuzi5FxkbOS7Q,19913
44
+ small_fish_gui/pipeline/spots.py,sha256=9hNOGnOZhrtrIORt8UGBcI-SGCh1XftcUGerkBwN-QY,2201
45
+ small_fish_gui/pipeline/test.py,sha256=w4ZMGDmUDXxVgWTlZ2TKw19W8q5gcE9gLMKe0SWnRrw,2827
46
+ small_fish_gui/pipeline/testing.ipynb,sha256=Rs7VQ7TImNyUzT2_59JgbOjR5_Qs-0NjHHnqS87eiwA,76481
47
+ small_fish_gui/pipeline/utils.py,sha256=run6qtqCAe_mFnE3o1CnmF1xBBmK3ydgc8-jOV9P-_w,448
48
+ small_fish_gui-1.9.4.dist-info/METADATA,sha256=Bgc5DOz2cWZrBxt8V9ePZ2d40tTDmDwhDcYp9yHGKgk,2634
49
+ small_fish_gui-1.9.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
50
+ small_fish_gui-1.9.4.dist-info/licenses/LICENSE,sha256=-iFy8VGBYs5VsHglKpk4D-hxqQ2jMJaqmfq_ulIzDks,1303
51
+ small_fish_gui-1.9.4.dist-info/RECORD,,
@@ -1,21 +0,0 @@
1
- # .readthedocs.yaml
2
- # Read the Docs configuration file
3
- # See for details
4
-
5
- # Required
6
- version: 2
7
-
8
- # Set the OS, Python version and other tools you might need
9
- build:
10
- os: ubuntu-22.04
11
- tools:
12
- python: "3.8"
13
-
14
- # Build documentation in the "docs/" directory with Sphinx
15
- sphinx:
16
- configuration: docs/conf.py
17
-
18
- # Optionally build your docs in additional formats such as PDF and ePub
19
- formats:
20
- - pdf
21
- - epub
@@ -1,52 +0,0 @@
1
- small_fish_gui/.readthedocs.yaml,sha256=r2T0e_In8X8l0_ZwgPvuoWQ9c0PE9bSpFzV2W6EzW3g,409
2
- small_fish_gui/LICENSE,sha256=-iFy8VGBYs5VsHglKpk4D-hxqQ2jMJaqmfq_ulIzDks,1303
3
- small_fish_gui/README.md,sha256=4RpEXKZW5vH6sUWeZb88yr1TLLPi20PqOk7KdA9O9Hk,4234
4
- small_fish_gui/Segmentation example.jpg,sha256=opfiSbjmfF6z8kBs08sg_FNR2Om0AcMPU5sSwSLHdoQ,215038
5
- small_fish_gui/__init__.py,sha256=CweT7xLrnaM2nluNztpNf3JaNncL7gHLFz2SvVG1iZs,1941
6
- small_fish_gui/__main__.py,sha256=jjFNnf-l4jCJI16epq2KOaKmgtUAe9lSNdPj5fpxrDk,1143
7
- small_fish_gui/hints.py,sha256=_AhC-Th36ELxinjMyGtjIqJfZkISPr1YwhQ9ifD9Kj4,1926
8
- small_fish_gui/napari_detection_example.png,sha256=l5EZlrbXemLiGqb5inSVsD6Kko1Opz528-go-fBfrw8,977350
9
- small_fish_gui/requirements.txt,sha256=9OMfUAnLdHevq6w_fVoDmVmkSMJeFofkOK_86_fu9C0,321
10
- small_fish_gui/utils.py,sha256=LM6QW2ono_LIRv7JXIIq7ZxxbDXqBtZ5uR9gjKJfwM8,1903
11
- small_fish_gui/.github/workflows/python-publish.yml,sha256=5Ltnuhw9TevhzndlBmdUgYMnS73xEAxSyd1u8DHdn5s,1084
12
- small_fish_gui/batch/__init__.py,sha256=ku2_Yate-UG89Q0BmE2B9kFV4kOz-u9Lf2lj6VsdFXs,127
13
- small_fish_gui/batch/input.py,sha256=mqnP8LBhyNbtlcqjVlUiVeuHw4YxOX3GgzJbq03isKE,1477
14
- small_fish_gui/batch/integrity.py,sha256=jIJH0c_M_7gSET32iKWEznHIad0OwPNvJurA9rivTJ0,4851
15
- small_fish_gui/batch/pipeline.py,sha256=EUUY0L6JvUYyF1SqJ1KdQHKKR1jhxsHSCyBm7nnB7mU,9157
16
- small_fish_gui/batch/prompt.py,sha256=Ob6Cml3IJTInMJ_9kSwLOKzwna7igbk91D2eaA7I1bo,18849
17
- small_fish_gui/batch/test.py,sha256=q04a1YstnDsxy2Bi5563BfcOU-O3VPE9c5WSJjvFjMg,211
18
- small_fish_gui/batch/update.py,sha256=AFG2oW5zfbNPJbb1jqbkMexPB8NoR4ZoftqpO3cAsok,5042
19
- small_fish_gui/batch/utils.py,sha256=JGRgaPcNQ5V2Hr8ObtmmMKqm3fB237Iym6aBawWY8Oo,1782
20
- small_fish_gui/batch/values.txt,sha256=eS19O1pdj0HYfwGUlWIpkvfNZQFxA3F4BDR8qahXh28,999
21
- small_fish_gui/gui/__init__.py,sha256=xQ_BfYcnQmKZtx_0leO4OmbkLNLv49ZPqEu_UXMgmDc,867
22
- small_fish_gui/gui/_napari_widgets.py,sha256=8IMppaPZU37ANdZwTZOhwqCEly0hokzYL7UIVIixGns,3022
23
- small_fish_gui/gui/animation.py,sha256=rnNP5FPp06Hu-R33c4AVTCknALBbxT2YlsKFCXHAp9k,981
24
- small_fish_gui/gui/help_module.py,sha256=XvGCNIcEGRG8ESJ55poCPhBM60Bl4w_ZxoVp-Ev6lTo,9612
25
- small_fish_gui/gui/layout.py,sha256=cA8ddzwbxVqTl5-VOoKvYKP0Fki17x2dczidSdW3ayA,14186
26
- small_fish_gui/gui/napari_visualiser.py,sha256=BSoLZtBBdbL407xrio3ZzaU_ZdP7I2T34-zQFntxwEs,14539
27
- small_fish_gui/gui/prompts.py,sha256=akphsDghaUngmqz3yBpyMPeTrRfye-Flkyixc9JSs74,15406
28
- small_fish_gui/gui/testing.ipynb,sha256=5xoMDR2a3aa4q8KoEoJ22HrcWDyHkCF4arVeVVm7ovs,71500
29
- small_fish_gui/gui/screenshot/general_help_screenshot.png,sha256=X4E6Td5f04K-pBUPDaBJRAE3D5b8fuEdiAUKhkIDr-0,54210
30
- small_fish_gui/gui/screenshot/mapping_help_screenshot.png,sha256=HcuRh5TYciUogUasza5vZ_QSshaiHsskQK23mh9vQS8,34735
31
- small_fish_gui/gui/screenshot/segmentation_help_screenshot.png,sha256=rbSgIydT0gZtfMh1qk4mdMbEIyCaakvHmxa2eOrLwO0,118944
32
- small_fish_gui/interface/__init__.py,sha256=_yCOvJjrMGVeGx9Lkyqp7t3fAztt67w2ZKLPj8_kfYc,277
33
- small_fish_gui/interface/image.py,sha256=VBSfIVcR50aJxxbD_ILflPX4esW9lXPArfHpVQynzCc,1100
34
- small_fish_gui/interface/inoutput.py,sha256=f20t9WDub8xLELCYGMvTsB3LzSxYusnpkMYQy9LrNwU,5026
35
- small_fish_gui/interface/testing.py,sha256=MMWNzAUE_Le3fqt2HY9rLXHQKv5c8ujON2PTooNnyLw,397
36
- small_fish_gui/pipeline/__init__.py,sha256=Oww6dcuvnktl5jFKLriz8ZXObKo9MkneE739A8C1reY,739
37
- small_fish_gui/pipeline/_colocalisation.py,sha256=oNMKfl2sUmFR4ipHEfvVbkOLf94_dmE-ay_co6kt2T0,21231
38
- small_fish_gui/pipeline/_custom_errors.py,sha256=tQ-AUhgzIFpK30AZiQQrtHCHyGVRDdAoIjzL0Fk-1pA,43
39
- small_fish_gui/pipeline/_preprocess.py,sha256=IrkQp_YCVFPrwElCEn-alpVChfLbR_0KAdb0WV2BfKI,15089
40
- small_fish_gui/pipeline/_signaltonoise.py,sha256=7A9t7xu7zghI6cr201Ldm-LjJ5NOuP56VSeJ8KIzcUo,8497
41
- small_fish_gui/pipeline/actions.py,sha256=7DmChUin3Zct7utVKj4zRpSMu4i5m2ctheOevbNCxa8,15745
42
- small_fish_gui/pipeline/detection.py,sha256=X2SmfHTnb2322PimxkXJ9gEco2cCZQ3eCKhfCRzk6hg,34953
43
- small_fish_gui/pipeline/main.py,sha256=2Oi6wz9jG9LA2gclTkIeFolJ4AON5AN6fFldOQsaXGw,4829
44
- small_fish_gui/pipeline/segmentation.py,sha256=MtGOcGWJPaJo7oa0YG2qB7LwDLIogJHCioSQxFecUqc,19911
45
- small_fish_gui/pipeline/spots.py,sha256=9hNOGnOZhrtrIORt8UGBcI-SGCh1XftcUGerkBwN-QY,2201
46
- small_fish_gui/pipeline/test.py,sha256=w4ZMGDmUDXxVgWTlZ2TKw19W8q5gcE9gLMKe0SWnRrw,2827
47
- small_fish_gui/pipeline/testing.ipynb,sha256=eMynROxPIa5uW6E2nb_CwA4X4Peiqa4QS68JcADrAnM,76479
48
- small_fish_gui/pipeline/utils.py,sha256=run6qtqCAe_mFnE3o1CnmF1xBBmK3ydgc8-jOV9P-_w,448
49
- small_fish_gui-1.9.2.dist-info/METADATA,sha256=Bq71I80yaGJukLnxynPExQGh5i8hwxHKMfi2sreR0YQ,2567
50
- small_fish_gui-1.9.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
51
- small_fish_gui-1.9.2.dist-info/licenses/LICENSE,sha256=-iFy8VGBYs5VsHglKpk4D-hxqQ2jMJaqmfq_ulIzDks,1303
52
- small_fish_gui-1.9.2.dist-info/RECORD,,