small-fish-gui 1.9.1__tar.gz → 1.9.3__tar.gz

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 (53) hide show
  1. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/PKG-INFO +2 -2
  2. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/pyproject.toml +2 -2
  3. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/README.md +11 -1
  4. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/__init__.py +1 -1
  5. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/__main__.py +1 -1
  6. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/batch/integrity.py +1 -1
  7. small_fish_gui-1.9.3/src/small_fish_gui/batch/pipeline.py +254 -0
  8. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/batch/prompt.py +1 -1
  9. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/batch/test.py +1 -1
  10. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/batch/update.py +1 -1
  11. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/batch/utils.py +1 -1
  12. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/gui/animation.py +1 -1
  13. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/gui/help_module.py +1 -1
  14. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/gui/layout.py +1 -1
  15. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/gui/napari_visualiser.py +4 -6
  16. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/gui/prompts.py +1 -1
  17. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/interface/inoutput.py +14 -3
  18. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/interface/testing.py +1 -1
  19. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/pipeline/_colocalisation.py +3 -2
  20. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/pipeline/_preprocess.py +1 -1
  21. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/pipeline/actions.py +18 -8
  22. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/pipeline/detection.py +24 -10
  23. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/pipeline/main.py +1 -1
  24. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/pipeline/segmentation.py +1 -1
  25. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/pipeline/testing.ipynb +2 -2
  26. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/requirements.txt +1 -1
  27. small_fish_gui-1.9.1/src/small_fish_gui/.readthedocs.yaml +0 -21
  28. small_fish_gui-1.9.1/src/small_fish_gui/batch/pipeline.py +0 -228
  29. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/LICENSE +0 -0
  30. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/README.md +0 -0
  31. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/.github/workflows/python-publish.yml +0 -0
  32. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/LICENSE +0 -0
  33. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/Segmentation example.jpg +0 -0
  34. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/batch/__init__.py +0 -0
  35. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/batch/input.py +0 -0
  36. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/batch/values.txt +0 -0
  37. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/gui/__init__.py +0 -0
  38. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/gui/_napari_widgets.py +0 -0
  39. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/gui/screenshot/general_help_screenshot.png +0 -0
  40. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/gui/screenshot/mapping_help_screenshot.png +0 -0
  41. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/gui/screenshot/segmentation_help_screenshot.png +0 -0
  42. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/gui/testing.ipynb +0 -0
  43. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/hints.py +0 -0
  44. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/interface/__init__.py +0 -0
  45. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/interface/image.py +0 -0
  46. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/napari_detection_example.png +0 -0
  47. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/pipeline/__init__.py +0 -0
  48. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/pipeline/_custom_errors.py +0 -0
  49. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/pipeline/_signaltonoise.py +0 -0
  50. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/pipeline/spots.py +0 -0
  51. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/pipeline/test.py +0 -0
  52. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/pipeline/utils.py +0 -0
  53. {small_fish_gui-1.9.1 → small_fish_gui-1.9.3}/src/small_fish_gui/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: small_fish_gui
3
- Version: 1.9.1
3
+ Version: 1.9.3
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
6
  Project-URL: Issues, https://github.com/2Echoes/small_fish/issues
@@ -13,6 +13,7 @@ Requires-Python: >=3.8
13
13
  Requires-Dist: big-fish==0.6.2
14
14
  Requires-Dist: cellpose==3.0.7
15
15
  Requires-Dist: czifile==2019.7.2
16
+ Requires-Dist: freesimplegui==5.1.1
16
17
  Requires-Dist: imageio==2.34.0
17
18
  Requires-Dist: napari-console==0.0.9
18
19
  Requires-Dist: napari-plugin-engine==0.2.0
@@ -23,7 +24,6 @@ Requires-Dist: numpy==1.24.4
23
24
  Requires-Dist: openpyxl==3.1.2
24
25
  Requires-Dist: pandas==1.5.3
25
26
  Requires-Dist: pyarrow==11.0.0
26
- Requires-Dist: pysimplegui==4.60.5
27
27
  Requires-Dist: scikit-image==0.19.1
28
28
  Requires-Dist: scikit-learn==1.3.2
29
29
  Requires-Dist: scipy==1.9.1
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "small_fish_gui"
7
- version = "1.9.1"
7
+ version = "1.9.3"
8
8
  authors = [
9
9
  { name="Slimani Floric", email="floric.slimani@live.com" },
10
10
  ]
@@ -28,7 +28,7 @@ dependencies = [
28
28
  "napari-svg==0.1.10",
29
29
  "numpy==1.24.4",
30
30
  "pandas==1.5.3",
31
- "PySimpleGUI==4.60.5",
31
+ "FreeSimpleGUI==5.1.1",
32
32
  "scipy==1.9.1",
33
33
  "scikit-image==0.19.1",
34
34
  "scikit-learn==1.3.2",
@@ -1,3 +1,7 @@
1
+ ***INSTALATTION ISSUE : Currently the package cannot be installed due to a package deletion on pypi. I will migrate the code to a free, open source gui package and update the dependecies list***
2
+
3
+ --> Requirements have been updated, pip installation is still not working but it is possible to install through git cloning
4
+
1
5
  # Small Fish
2
6
  **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.
3
7
 
@@ -5,7 +9,7 @@ Cell segmentation (**2D**) is peformed using *cellpose* (published work) : https
5
9
 
6
10
  Spot detection is performed via *big-fish* (published work) : https://github.com/fish-quant/big-fish
7
11
 
8
- **Time stacks are not supported.**
12
+ ***Small Fish is bulding a [wiki](https://github.com/2Echoes/small_fish_gui/wiki) ! Make sure to check it out.***
9
13
 
10
14
  ## What can you do with small fish ?
11
15
 
@@ -93,5 +97,11 @@ Note that for training it is recommended to first set up your GPU as training co
93
97
  ## Developpement
94
98
 
95
99
  Optional features to include in future versions :
100
+
101
+ **Major Dev**
96
102
  - time stack (which would include cell tracking)
97
103
  - 3D segmentation
104
+
105
+ **Minor features**
106
+ - allows npz files with multiple masks in load segmentation by asking user which one to select
107
+ - fix parquet format or replace to another compressed format
@@ -38,4 +38,4 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38
38
  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39
39
 
40
40
  """
41
- __version__ = "1.9.1"
41
+ __version__ = "1.9.3"
@@ -1,5 +1,5 @@
1
1
  import sys, subprocess
2
- import PySimpleGUI as sg
2
+ import FreeSimpleGUI as sg
3
3
 
4
4
  from small_fish_gui import __version__
5
5
 
@@ -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
@@ -0,0 +1,254 @@
1
+ """
2
+ Submodule keeping necessary calls from main pipeline for batch processing.
3
+ """
4
+
5
+ import os
6
+ import pandas as pd
7
+ import FreeSimpleGUI as sg
8
+
9
+ from ..hints import pipeline_parameters
10
+
11
+ from .input import open_image
12
+ from ..interface import write_results
13
+ from ..pipeline import reorder_shape, reorder_image_stack, prepare_image_detection
14
+ from ..pipeline import cell_segmentation, launch_detection, launch_features_computation
15
+ from ..pipeline import launch_spots_extraction
16
+ from ..pipeline import get_nucleus_signal
17
+ from ..pipeline import _cast_segmentation_parameters, convert_parameters_types
18
+ from ..pipeline import plot_segmentation, output_spot_tiffvisual
19
+ from ..utils import get_datetime
20
+
21
+ def window_print(window: sg.Window, *args) :
22
+ print(*args)
23
+ window.refresh()
24
+
25
+ def batch_pipeline(
26
+ batch_window : sg.Window,
27
+ batch_progress_bar : sg.ProgressBar,
28
+ progress_count : sg.Text,
29
+ parameters : pipeline_parameters,
30
+ filenames_list : list,
31
+ do_segmentation : bool,
32
+ map_ : dict,
33
+ results_df : pd.DataFrame,
34
+ cell_results_df : pd.DataFrame,
35
+ is_3D,
36
+ last_acquisition_id=0,
37
+ ) :
38
+
39
+ #Extracting parameters
40
+ input_path = parameters['Batch_folder']
41
+ output_path = parameters['output_folder']
42
+ batch_name = parameters['batch_name']
43
+ time = '_' + get_datetime()
44
+
45
+ #Preparing folder
46
+ window_print(batch_window,"Creating folders for output...")
47
+ main_dir = output_path + "/" + batch_name + time + "/"
48
+ os.makedirs(main_dir + "results/", exist_ok=True)
49
+ if parameters['save segmentation'] : os.makedirs(main_dir + "segmentation/", exist_ok=True)
50
+ if parameters['save detection'] : os.makedirs(main_dir + "detection/", exist_ok=True)
51
+ if parameters['extract spots'] : os.makedirs(main_dir + "results/spots_extraction", exist_ok=True)
52
+
53
+ #Setting spot detection dimension
54
+ parameters['dim'] = 3 if is_3D else 2
55
+
56
+ #Pipeline loop
57
+ window_print(batch_window,"Launching batch analysis...")
58
+ batch_progress_bar.update(max=len(filenames_list))
59
+ filenames_list.sort()
60
+
61
+
62
+ error_log = open(main_dir + "error_log", mode='w')
63
+ error_count = 0
64
+
65
+ for acquisition_id, file in enumerate(filenames_list) :
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']
99
+ )
100
+
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
+ )
118
+
119
+ else :
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
+ )
137
+
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"
156
+ )
157
+
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,
193
+ )
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,
209
+ path= main_dir + "results/",
210
+ filename=batch_name,
211
+ do_excel= parameters["xlsx"],
212
+ do_feather= parameters["feather"],
213
+ do_csv= parameters["csv"],
214
+ overwrite=True,
215
+ )
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
+
246
+
247
+ batch_progress_bar.update(current_count= acquisition_id+1, max= len(filenames_list))
248
+ progress_count.update(value=str(acquisition_id+1))
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
+
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
 
@@ -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
@@ -123,7 +123,7 @@ def __update_clusters(new_clusters: np.ndarray, spots: np.ndarray, voxel_size, c
123
123
  Outdated. previous behaviour.
124
124
  """
125
125
  if len(new_clusters) == 0 : return new_clusters
126
- if len(spots) == 0 : return np.empty(shape=(0,2+len(voxel_size)))
126
+ if len(spots) == 0 : return np.empty(shape=(0,2+len(voxel_size)), dtype=int)
127
127
 
128
128
  if len(new_clusters[0]) in [2,3] :
129
129
  new_clusters = np.concatenate([
@@ -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))
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,14 +222,13 @@ 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))
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()
230
230
  new_clusters = np.concatenate([new_clusters, new_cluster_id], axis=1)
231
231
 
232
- print("After concatenate new clusters shape = {0}".format(new_clusters.shape))
233
232
 
234
233
  new_spots, new_clusters = _update_clusters(
235
234
  old_spots =spots,
@@ -243,7 +242,6 @@ def correct_spots(
243
242
  null_value= -2
244
243
  )
245
244
 
246
- print("After _update_cluster\nnew_clusters shape = {0}\nnew_spots shape = {1}".format(new_clusters.shape, new_spots.shape))
247
245
 
248
246
  else : new_clusters = None
249
247
 
@@ -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
@@ -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
@@ -183,7 +183,7 @@ def cluster_detection(spots, voxel_size, radius = 350, nb_min_spots = 4, keys_to
183
183
  elif isinstance(keys_to_compute, list) : pass
184
184
  else : raise TypeError("Wrong type for keys_to_compute. Should be list[str] or str. It is {0}".format(type(keys_to_compute)))
185
185
  if len(spots) == 0 :
186
- res = {'clustered_spots' : [], 'clusters' : [], 'clustered_spots_dataframe' : pd.DataFrame(columns= ["id", "cluster_id", "z", "y", "x"]), 'clusters_dataframe' : pd.DataFrame(columns= ["id", "z", "y", "x", "spot_number"])}
186
+ res = {'clustered_spots' : np.empty(shape=(0,len(voxel_size) + 1), dtype=int), 'clusters' : np.empty(shape=(0,len(voxel_size) + 2), dtype=int), 'clustered_spots_dataframe' : pd.DataFrame(columns= ["id", "cluster_id", "z", "y", "x"]), 'clusters_dataframe' : pd.DataFrame(columns= ["id", "z", "y", "x", "spot_number"])}
187
187
  return {key : res[key] for key in keys_to_compute}
188
188
  else : res = {}
189
189
  voxel_size = tuple([int(d) for d in voxel_size])
@@ -192,7 +192,7 @@ def cluster_detection(spots, voxel_size, radius = 350, nb_min_spots = 4, keys_to
192
192
 
193
193
  if 'clustered_spots' in keys_to_compute :
194
194
  res['clustered_spots'] = clustered_spots
195
-
195
+ voxel_size
196
196
  if 'clusters' in keys_to_compute :
197
197
  res['clusters'] = clusters
198
198
 
@@ -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(
@@ -407,9 +407,8 @@ def launch_cell_extraction(
407
407
 
408
408
  if do_clustering :
409
409
  if len(clusters) > 0 :
410
-
411
- free_spots = spots[spots_cluster_id == -1]
412
- clustered_spots = spots[spots_cluster_id != -1]
410
+ free_spots = spots[spots_cluster_id == -1].astype(int)
411
+ clustered_spots = spots[spots_cluster_id != -1].astype(int)
413
412
 
414
413
  other_coords = {
415
414
  'clusters_coords' : clusters,
@@ -471,6 +470,13 @@ def launch_cell_extraction(
471
470
  free_spots_coords = cell.get('free_spots')
472
471
  signal = cell['image']
473
472
 
473
+ if do_clustering :
474
+ if len(clusters) > 0 :
475
+ compute_foci = True
476
+ else :
477
+ compute_foci = False
478
+ else : compute_foci = False
479
+
474
480
  with np.errstate(divide= 'ignore', invalid= 'ignore') :
475
481
  features = classification.compute_features(
476
482
  cell_mask=cell_mask,
@@ -485,7 +491,7 @@ def launch_cell_extraction(
485
491
  compute_area=True,
486
492
  compute_dispersion=True,
487
493
  compute_distance=True,
488
- compute_foci= do_clustering and len(clusters) > 0,
494
+ compute_foci= compute_foci,
489
495
  compute_intranuclear=True,
490
496
  compute_protrusion=False,
491
497
  compute_topography=True
@@ -535,7 +541,8 @@ def launch_cell_extraction(
535
541
 
536
542
  features = [acquisition_id, cell_id, cell_bbox] + features
537
543
  features += [rna_coords, foci_coords, clustered_spots_coords, free_spots_coords]
538
- features += [len(clustered_spots_coords), len(free_spots_coords)]
544
+ features += [len(clustered_spots_coords) if type(clustered_spots_coords) != type(None) else None]
545
+ features += [len(free_spots_coords) if type(free_spots_coords) != type(None) else None]
539
546
 
540
547
  result_frame = pd.concat([
541
548
  result_frame,
@@ -703,7 +710,14 @@ def launch_features_computation(
703
710
  if user_parameters['segmentation_done'] :
704
711
  cell_result_dframe['name'] = name
705
712
  cell_result_dframe = cell_result_dframe.loc[:,['name'] + cell_result_col]
706
- 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
+
707
721
 
708
722
  return frame_results, cell_result_dframe
709
723
 
@@ -3,7 +3,7 @@ This script is called when software starts; it is the main loop.
3
3
  """
4
4
 
5
5
  import pandas as pd
6
- import PySimpleGUI as sg
6
+ import FreeSimpleGUI as sg
7
7
  from ..gui import hub_prompt
8
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
@@ -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,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,228 +0,0 @@
1
- """
2
- Submodule keeping necessary calls from main pipeline for batch processing.
3
- """
4
-
5
- import os
6
- import pandas as pd
7
- import PySimpleGUI as sg
8
-
9
- from ..hints import pipeline_parameters
10
-
11
- from .input import open_image
12
- from ..interface import write_results
13
- from ..pipeline import reorder_shape, reorder_image_stack, prepare_image_detection
14
- from ..pipeline import cell_segmentation, launch_detection, launch_features_computation
15
- from ..pipeline import launch_spots_extraction
16
- from ..pipeline import get_nucleus_signal
17
- from ..pipeline import _cast_segmentation_parameters, convert_parameters_types
18
- from ..pipeline import plot_segmentation, output_spot_tiffvisual
19
- from ..utils import get_datetime
20
-
21
- def window_print(window: sg.Window, *args) :
22
- print(*args)
23
- window.refresh()
24
-
25
- def batch_pipeline(
26
- batch_window : sg.Window,
27
- batch_progress_bar : sg.ProgressBar,
28
- progress_count : sg.Text,
29
- parameters : pipeline_parameters,
30
- filenames_list : list,
31
- do_segmentation : bool,
32
- map_ : dict,
33
- results_df : pd.DataFrame,
34
- cell_results_df : pd.DataFrame,
35
- is_3D,
36
- last_acquisition_id=0,
37
- ) :
38
-
39
- #Extracting parameters
40
- input_path = parameters['Batch_folder']
41
- output_path = parameters['output_folder']
42
- batch_name = parameters['batch_name']
43
- time = '_' + get_datetime()
44
-
45
- #Preparing folder
46
- window_print(batch_window,"Creating folders for output...")
47
- main_dir = output_path + "/" + batch_name + time + "/"
48
- os.makedirs(main_dir + "results/", exist_ok=True)
49
- if parameters['save segmentation'] : os.makedirs(main_dir + "segmentation/", exist_ok=True)
50
- if parameters['save detection'] : os.makedirs(main_dir + "detection/", exist_ok=True)
51
- if parameters['extract spots'] : os.makedirs(main_dir + "results/spots_extraction", exist_ok=True)
52
-
53
- #Setting spot detection dimension
54
- parameters['dim'] = 3 if is_3D else 2
55
-
56
- #Pipeline loop
57
- window_print(batch_window,"Launching batch analysis...")
58
- batch_progress_bar.update(max=len(filenames_list))
59
- filenames_list.sort()
60
- 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'],
111
- )
112
-
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
- )
131
-
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
- 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
- )
151
-
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,
172
- )
173
-
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,
209
- )
210
-
211
- if do_segmentation :
212
- cell_success = write_results(
213
- cell_results_df,
214
- path= main_dir + "results/",
215
- filename=batch_name + '_cell_result',
216
- do_excel= parameters["xlsx"],
217
- do_feather= parameters["feather"],
218
- do_csv= parameters["csv"],
219
- overwrite=True,
220
- )
221
-
222
- window_print(batch_window,"Sucessfully saved.")
223
-
224
-
225
- batch_progress_bar.update(current_count= acquisition_id+1, max= len(filenames_list))
226
- progress_count.update(value=str(acquisition_id+1))
227
- batch_window = batch_window.refresh()
228
- return results_df, cell_results_df, acquisition_id
File without changes
File without changes