small-fish-gui 1.10.4__py3-none-any.whl → 2.0.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 (39) hide show
  1. small_fish_gui/README.md +42 -70
  2. small_fish_gui/__init__.py +1 -1
  3. small_fish_gui/__main__.py +1 -1
  4. small_fish_gui/batch/integrity.py +8 -1
  5. small_fish_gui/batch/output.py +16 -0
  6. small_fish_gui/batch/pipeline.py +43 -24
  7. small_fish_gui/batch/prompt.py +44 -26
  8. small_fish_gui/batch/update.py +19 -3
  9. small_fish_gui/batch/utils.py +2 -0
  10. small_fish_gui/batch/values.txt +5 -5
  11. small_fish_gui/default_values.py +51 -0
  12. small_fish_gui/gui/__init__.py +3 -1
  13. small_fish_gui/gui/_napari_widgets.py +15 -4
  14. small_fish_gui/gui/layout.py +123 -54
  15. small_fish_gui/gui/napari_visualiser.py +12 -8
  16. small_fish_gui/gui/prompts.py +61 -74
  17. small_fish_gui/gui/tooltips.py +15 -0
  18. small_fish_gui/hints.py +23 -4
  19. small_fish_gui/illustrations/DetectionVitrine_filtre.png +0 -0
  20. small_fish_gui/illustrations/DetectionVitrine_signal.png +0 -0
  21. small_fish_gui/illustrations/FocciVitrine.png +0 -0
  22. small_fish_gui/illustrations/FocciVitrine_no_spots.png +0 -0
  23. small_fish_gui/illustrations/Segmentation2D.png +0 -0
  24. small_fish_gui/illustrations/Segmentation2D_with_labels.png +0 -0
  25. small_fish_gui/logo.png +0 -0
  26. small_fish_gui/{pipeline/main.py → main_menu.py} +16 -15
  27. small_fish_gui/pipeline/_colocalisation.py +60 -41
  28. small_fish_gui/pipeline/_preprocess.py +13 -12
  29. small_fish_gui/pipeline/actions.py +102 -14
  30. small_fish_gui/pipeline/detection.py +5 -1
  31. small_fish_gui/pipeline/segmentation.py +206 -73
  32. small_fish_gui/pipeline/spots.py +129 -5
  33. small_fish_gui/pipeline/testing.ipynb +1571 -2
  34. small_fish_gui/requirements.txt +4 -4
  35. {small_fish_gui-1.10.4.dist-info → small_fish_gui-2.0.1.dist-info}/METADATA +14 -16
  36. small_fish_gui-2.0.1.dist-info/RECORD +59 -0
  37. small_fish_gui-1.10.4.dist-info/RECORD +0 -49
  38. {small_fish_gui-1.10.4.dist-info → small_fish_gui-2.0.1.dist-info}/WHEEL +0 -0
  39. {small_fish_gui-1.10.4.dist-info → small_fish_gui-2.0.1.dist-info}/licenses/LICENSE +0 -0
small_fish_gui/README.md CHANGED
@@ -1,24 +1,51 @@
1
- # Small Fish
2
- **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.
1
+ # Small Fish - A User-Friendly Graphical Interface for smFISH Image Quantification
3
2
 
4
- Cell segmentation (**2D**) is peformed using *cellpose* (published work) : https://github.com/MouseLand/cellpose; compatible with your own cellpose models.
3
+ [![License: BSD-2-Clause](https://img.shields.io/badge/License-BSD_2--Clause-orange.svg)](https://opensource.org/licenses/BSD-2-Clause)
4
+ [![GitHub stars](https://img.shields.io/github/stars/SmallFishGUI/small_fish_gui.svg?style=social)](https://github.com/SmallFishGUI/small_fish_gui) [![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
5
5
 
6
- Spot detection is performed via *big-fish* (published work) : https://github.com/fish-quant/big-fish
6
+ **Small Fish** is a python application for smFish image analysis. It provides a ready to use graphical interface to synthetize state-of-the-art scientific packages into an automated workflow. Small Fish is designed to simplify images quantification and analysis for people without coding skills.
7
7
 
8
- ***Small Fish is bulding a [wiki](https://github.com/2Echoes/small_fish_gui/wiki) ! Make sure to check it out.***
8
+ Cell segmentation is peformed in 2D and 3D throught cellpose 4.0+(published work) : https://github.com/MouseLand/cellpose; compatible with your own cellpose models.
9
9
 
10
- ## What can you do with small fish ?
10
+ Spot detection is performed via *big-fish* a python implementation of FishQuant (published work) : https://github.com/fish-quant/big-fish.
11
+
12
+ ***The workflow is fully explained in the [wiki](https://github.com/2Echoes/small_fish_gui/wiki) ! Make sure to check it out.***
11
13
 
12
- - Single molecule quantification (including a lot of spatial features)
13
- - Foci/Transcription site quantification
14
- - Nuclear signal quantification
15
- - Signal to noise analysis
16
- - multichannel colocalisation
14
+ ## What can you do with small fish ?
17
15
 
18
- <img src="https://github.com/2Echoes/small_fish_gui/blob/main/Segmentation%20example.jpg" width="500" title="Cell segmentation with Cellpose" alt="Cell segmentation - cellpose">| <img src="https://github.com/2Echoes/small_fish_gui/blob/main/napari_detection_example.png" width="500" title="Spot detection; clustering visualisation on Napari" alt="detection; Napari example">
16
+ Single molecule quantification
17
+ ✅ Transcriptomics
18
+ ✅ Foci quantification
19
+ ✅ Transcription sites quantification
20
+ ✅ Nuclear signal quantification
21
+ ✅ Signal to noise analysis
22
+ ✅ Cell segmentation
23
+ ✅ Multichannel colocalisation
24
+
25
+ <p align="center">
26
+ <img src="https://raw.githubusercontent.com/SmallFishGUI/small_fish_gui/main/illustrations/Segmentation2D.png" width="500" title="Fish_signal" alt="Fish signal">
27
+ </p>
28
+ <p align="center"><strong>Raw 3D fish signal with dapi</p></strong>
29
+
30
+ <p align="center">
31
+ <img src="https://raw.githubusercontent.com/SmallFishGUI/small_fish_gui/main/illustrations/Segmentation2D_with_labels.png" width="500" title="Cell segmentation" alt="Segmentation">
32
+ </p>
33
+ <p align="center"><strong>2D segmentation</p></strong>
34
+
35
+ <p align="center">
36
+ <img src="https://raw.githubusercontent.com/SmallFishGUI/small_fish_gui/main/illustrations/FocciVitrine.png" width="500" title="Detection_signal" alt="Detection_signal">
37
+ </p>
38
+ <p align="center"><strong> 3D Spot detection</p></strong>
39
+
40
+ <p align="center">
41
+ <img src="https://raw.githubusercontent.com/SmallFishGUI/small_fish_gui/main/illustrations/FocciVitrine_no_spots.png" width="500" title="Detection filter" alt="detection">
42
+ </p>
43
+ <p align="center"><strong>Cluster detection</p></strong>
44
+
45
+ Analysis can be performed either fully interactively throught a Napari interface or performed automatically through a batch processing allowing for reproducible quantifications.
19
46
 
20
47
  ## Installation
21
- If you don't have a python installation yet I would recommend the [miniconda distribution](https://docs.anaconda.com/free/miniconda/miniconda-other-installer-links/); but any distribution should work.
48
+ If you don't have a python installation yet I would recommend the [miniconda distribution](https://docs.anaconda.com/free/miniconda/miniconda-other-installer-links/).
22
49
 
23
50
  It is higly recommanded to create a specific [conda](https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html) or [virtual](https://docs.python.org/3.6/library/venv.html) environnement to install small fish.
24
51
 
@@ -40,66 +67,11 @@ pip install napari[all]
40
67
 
41
68
  First activate your python environnement :
42
69
  ```bash
43
- activate small_fish
70
+ conda activate small_fish
44
71
  ```
45
72
  Then launch Small fish :
46
73
  ```bash
47
74
  python -m small_fish_gui
48
75
  ```
49
76
 
50
- ## Cellpose configuration
51
-
52
- For the following steps first activate your small fish environnement :
53
-
54
- ```bash
55
- conda activate small_fish
56
- ```
57
- ### Setting up your GPU for cellpose (Windows / Linux)
58
- This instructions describe how I installed CUDA and GPU cellpose on the machines I tested, unfortunatly, drivers installations don't always run smoothly, if you run into any difficulties please have a look at the *GPU version (CUDA) on Windows or Linux* section of the [cellpose documentation](https://github.com/MouseLand/cellpose) for assistance.
59
-
60
- First step is to check that your GPU is CUDA compatible which it should be if from the brand NVIIDA.
61
- Then you need to install CUDA from the [NVIDIA archives](https://developer.nvidia.com/cuda-toolkit-archive), any 11.x version should work but I recommend the 11.8 version.
62
-
63
- Finally we need to make some modifcation to your small fish environnement :
64
-
65
- Remove the CPU version of torch
66
-
67
- ```bash
68
- pip uninstall torch
69
- ```
70
- Then install pytorch and cudatoolkit :
71
-
72
- ```bash
73
- conda install pytorch==1.12.0 cudatoolkit=11.3 -c pytorch
74
- ```
75
- If the installation succeeded next time your run segmentation with small fish you should see the "GPU is ON" notice upon entering the segmentation parameters.
76
- If you run into any problems I would recommend following the official cellpose instructions as mentionned above.
77
-
78
-
79
- ### Training cellpose
80
- If you want to train your own cellpose model or import custom model from exterior source I recommend doing so from the cellpose GUI. Note that Small fish uses mean projection to segment images in 2D, if you want to retrain a cellpose model to fit your data it is recommended to do so on mean or max projection of your data.
81
-
82
- To install the GUI run :
83
-
84
- ```bash
85
- pip install cellpose[gui]
86
- ```
87
- Then to run cellpose
88
- ```bash
89
- cellpose
90
- ```
91
- Note that for training it is recommended to first set up your GPU as training computation can be quite long otherwise. To get started with how to train your models you can watch the [video](https://www.youtube.com/watch?v=5qANHWoubZU) from cellpose authors.
92
-
93
- ## Developpement
94
-
95
- Optional features to include in future versions :
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.
105
- * Foci merge tool in Napari
77
+ You are all set! Try it yourself or check the [get started](https://github.com/2Echoes/small_fish_gui/wiki/Get-started) section in the wiki.
@@ -37,7 +37,7 @@ 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
39
  """
40
- __version__ = "1.10.4"
40
+ __version__ = "2.0.1"
41
41
  __wiki__ = "https://github.com/2Echoes/small_fish_gui/wiki"
42
42
 
43
43
  import os
@@ -9,7 +9,7 @@ AVAILABLE_ARGUMENTS = {
9
9
 
10
10
 
11
11
  def main():
12
- import small_fish_gui.pipeline.main
12
+ import small_fish_gui.main_menu
13
13
 
14
14
  def _get_version() :
15
15
  return __version__
@@ -63,11 +63,18 @@ def check_channel_map_integrity(
63
63
  ) :
64
64
 
65
65
  #Check integrity
66
- channels_values = np.array(list(maping.values()), dtype= int)
66
+ try :
67
+ channels_values = np.array(list(maping.values()), dtype= int)
68
+ except Exception :
69
+ res = False
70
+ sg.popup("Incorrect values for channel mapping. ({0})".format(maping.values()))
71
+ return res
72
+
67
73
  total_channels = len(maping)
68
74
  unique_channel = len(np.unique(channels_values))
69
75
  res= True
70
76
 
77
+
71
78
  if expected_dim != total_channels :
72
79
  sg.popup("Image has {0} dimensions but {1} were mapped.".format(expected_dim, total_channels))
73
80
  res = False
@@ -0,0 +1,16 @@
1
+ import numpy as np
2
+ import os
3
+
4
+ def output_masks(
5
+ batch_path : str,
6
+ acquisition_name : str,
7
+ nucleus_label : np.ndarray,
8
+ cytoplasm_label : np.ndarray = None,
9
+ ) :
10
+
11
+ os.makedirs(batch_path + "/segmentation_masks/", exist_ok=True)
12
+ output_path = batch_path + "/segmentation_masks/{0}".format(acquisition_name)
13
+
14
+ np.save(output_path + "_nucleus.npy", arr= nucleus_label)
15
+ if type(cytoplasm_label) != type(None) :
16
+ np.save(output_path + "_cytoplasm.npy", arr= cytoplasm_label)
@@ -2,13 +2,15 @@
2
2
  Submodule keeping necessary calls from main pipeline for batch processing.
3
3
  """
4
4
 
5
- import os
5
+ import os, traceback
6
6
  import pandas as pd
7
7
  import FreeSimpleGUI as sg
8
+ import numpy as np
8
9
 
9
10
  from ..hints import pipeline_parameters
10
11
 
11
12
  from .input import open_image
13
+ from .output import output_masks
12
14
  from ..interface import write_results
13
15
  from ..pipeline import reorder_shape, reorder_image_stack, prepare_image_detection
14
16
  from ..pipeline import cell_segmentation, launch_detection, launch_features_computation
@@ -17,6 +19,7 @@ from ..pipeline import get_nucleus_signal
17
19
  from ..pipeline import _cast_segmentation_parameters, convert_parameters_types
18
20
  from ..pipeline import plot_segmentation, output_spot_tiffvisual
19
21
  from ..utils import get_datetime
22
+ from .utils import clean_filename
20
23
 
21
24
  def window_print(window: sg.Window, *args) :
22
25
  print(*args)
@@ -62,7 +65,6 @@ def batch_pipeline(
62
65
  filenames_list.sort()
63
66
 
64
67
 
65
- error_log = open(main_dir + "error_log", mode='w')
66
68
  error_count = 0
67
69
 
68
70
  #These columns usually kept for coloc analysis will be dropped for memory gain in batch mode
@@ -100,11 +102,18 @@ def batch_pipeline(
100
102
  cytoplasm_label, nucleus_label = cell_segmentation(
101
103
  im_seg,
102
104
  cyto_model_name= parameters['cyto_model_name'],
103
- cyto_diameter= parameters['cytoplasm diameter'],
105
+ cyto_diameter= parameters['cytoplasm_diameter'],
104
106
  nucleus_model_name= parameters['nucleus_model_name'],
105
- nucleus_diameter= parameters['nucleus diameter'],
106
- channels=[parameters['cytoplasm channel'], parameters['nucleus channel']],
107
- do_only_nuc=parameters['Segment only nuclei']
107
+ nucleus_diameter= parameters['nucleus_diameter'],
108
+ channels=[parameters['cytoplasm_channel'], parameters['nucleus_channel']],
109
+ anisotropy= parameters['anisotropy'],
110
+ nucleus_3D_segmentation=parameters['nucleus_segmentation_3D'],
111
+ cyto_3D_segmentation= parameters['cytoplasm_segmentation_3D'],
112
+ do_only_nuc=parameters['segment_only_nuclei'],
113
+ flow_threshold_cyto=parameters['flow_threshold_cyto'],
114
+ flow_threshold_nuc=parameters['flow_threshold_cyto'],
115
+ cellprob_threshold_cyto=parameters['cellprob_threshold_cyto'],
116
+ cellprob_threshold_nuc=parameters['cellprob_threshold_nuc'],
108
117
  )
109
118
 
110
119
  parameters['segmentation_done'] = True
@@ -117,12 +126,20 @@ def batch_pipeline(
117
126
 
118
127
  if parameters['save segmentation'] :
119
128
  plot_segmentation(
120
- cyto_image=im_seg[parameters['cytoplasm channel']],
129
+ cyto_image=im_seg[parameters['cytoplasm_channel']],
121
130
  cyto_label= cytoplasm_label,
122
- nuc_image= im_seg[parameters['nucleus channel']],
131
+ nuc_image= im_seg[parameters['nucleus_channel']],
123
132
  nuc_label=nucleus_label,
124
- path= main_dir + "segmentation/" + file,
125
- do_only_nuc= parameters['Segment only nuclei'],
133
+ path= main_dir + "segmentation/" + clean_filename(file),
134
+ do_only_nuc= parameters['segment_only_nuclei'],
135
+ )
136
+
137
+ if parameters["save_masks"] :
138
+ output_masks(
139
+ batch_path= main_dir,
140
+ acquisition_name= clean_filename(file),
141
+ nucleus_label= nucleus_label,
142
+ cytoplasm_label= cytoplasm_label if not parameters['segment_only_nuclei'] else None,
126
143
  )
127
144
 
128
145
  else :
@@ -161,7 +178,7 @@ def batch_pipeline(
161
178
  image,
162
179
  spots_list= spots_list,
163
180
  dot_size=2,
164
- path_output= main_dir + "detection/" + file + "_spot_detection.tiff"
181
+ path_output= main_dir + "detection/" + clean_filename(file) + "_spot_detection.tiff"
165
182
  )
166
183
 
167
184
  #4. Spots extraction
@@ -172,8 +189,7 @@ def batch_pipeline(
172
189
  #Only spots have one file per image to avoir memory overload
173
190
  parameters['do_spots_excel'] = parameters['xlsx']
174
191
  parameters['do_spots_csv'] = parameters['csv']
175
- parameters['do_spots_feather'] = parameters['feather']
176
- parameters['spots_filename'] = "spots_extractions_{0}".format(file)
192
+ parameters['spots_filename'] = "spots_extractions_{0}".format(clean_filename(file))
177
193
  parameters['spots_extraction_folder'] = main_dir + "results/spots_extraction/"
178
194
 
179
195
  launch_spots_extraction(
@@ -195,8 +211,8 @@ def batch_pipeline(
195
211
  spots=spots,
196
212
  clusters=clusters,
197
213
  spots_cluster_id=spot_cluster_id,
198
- nucleus_label = nucleus_label,
199
- cell_label= cytoplasm_label,
214
+ nucleus_label = nucleus_label if nucleus_label.ndim == 2 else np.max(nucleus_label,axis=0),
215
+ cell_label= cytoplasm_label if cytoplasm_label.ndim == 2 else np.max(cytoplasm_label, axis=0),
200
216
  user_parameters=parameters,
201
217
  frame_results=frame_result,
202
218
  )
@@ -226,7 +242,6 @@ def batch_pipeline(
226
242
  path= main_dir + "results/",
227
243
  filename=batch_name,
228
244
  do_excel= parameters["xlsx"],
229
- do_feather= parameters["feather"],
230
245
  do_csv= parameters["csv"],
231
246
  overwrite=True,
232
247
  batch_mode=True,
@@ -242,7 +257,6 @@ def batch_pipeline(
242
257
  path= main_dir + "results/",
243
258
  filename=batch_name + '_cell_result',
244
259
  do_excel= parameters["xlsx"],
245
- do_feather= parameters["feather"],
246
260
  do_csv= parameters["csv"],
247
261
  overwrite=True,
248
262
  batch_mode=True,
@@ -257,15 +271,20 @@ def batch_pipeline(
257
271
 
258
272
  except Exception as error :
259
273
 
260
- error_count +=1
261
- print("Exception raised for acquisition, writting error in error log.")
274
+
275
+ with open(main_dir + "error_log", mode='a') as error_log :
276
+
277
+ error_count +=1
278
+ print("Exception raised for acquisition, writting error in error log.")
262
279
 
263
- log = [
264
- f"Error raised during acquisition {acquisition_id}.\n"
265
- ]
266
- log.append(str(error) + '\n')
280
+ log = [
281
+ f"Error raised during acquisition {acquisition_id}.\n",
282
+ f"{error}\n",
283
+ f"traceback :\n{traceback.format_exc()}"
284
+ ]
285
+
267
286
 
268
- error_log.writelines(log)
287
+ error_log.writelines(log)
269
288
 
270
289
  print("Ignoring current acquisition and proceeding to next one.")
271
290
  continue
@@ -4,6 +4,7 @@ Submodule with main function to call to launch batch mode.
4
4
 
5
5
  import os
6
6
  import FreeSimpleGUI as sg
7
+ import small_fish_gui.default_values as default
7
8
 
8
9
  from .utils import get_elmt_from_key, create_map, call_auto_map
9
10
  from .pipeline import batch_pipeline
@@ -24,7 +25,17 @@ def batch_promp(
24
25
 
25
26
 
26
27
  #LOAD FILES
27
- files_table = sg.Table(values=files_values, headings=['Filenames'], col_widths=100, max_col_width= 200, def_col_width=100, num_rows= 10, auto_size_columns=False)
28
+ files_table = sg.Table(
29
+ values=files_values,
30
+ headings=['Filenames'],
31
+ col_widths=100,
32
+ max_col_width= 200,
33
+ def_col_width=100,
34
+ num_rows= 10,
35
+ auto_size_columns=False,
36
+ expand_y=True,
37
+ justification='left',
38
+ )
28
39
 
29
40
  #DIMENSION SANITY
30
41
  sanity_progress = sg.ProgressBar(10, size_px=(500,10), border_width=2)
@@ -45,11 +56,11 @@ def batch_promp(
45
56
  #Input tab
46
57
  input_layout = _input_parameters_layout(
47
58
  ask_for_segmentation=True,
48
- is_3D_stack_preset= preset.setdefault("is_3D_stack" ,False),
59
+ is_3D_stack_preset= preset.setdefault("is_3D_stack" ,default.IS_3D_STACK),
49
60
  time_stack_preset=False,
50
- multichannel_preset=preset.setdefault("is_multichannel" ,False),
51
- do_dense_regions_deconvolution_preset=preset.setdefault("do_dense_regions_deconvolution" ,False),
52
- do_clustering_preset= preset.setdefault("do_cluster_computation", False),
61
+ multichannel_preset=preset.setdefault("is_multichannel" ,default.IS_MULTICHANNEL),
62
+ do_dense_regions_deconvolution_preset=preset.setdefault("do_dense_regions_deconvolution", default.DO_DENSE_REGIONS_DECONVOLUTION),
63
+ do_clustering_preset= preset.setdefault("do_cluster_computation", default.DO_CLUSTER_COMPUTATION),
53
64
  do_Napari_correction=False,
54
65
  do_segmentation_preset= preset.setdefault("segmentation_done", False),
55
66
  )
@@ -74,19 +85,20 @@ def batch_promp(
74
85
 
75
86
  #Segmentation tab
76
87
  segmentation_layout = _segmentation_layout(
77
- multichannel=True,
78
- cytoplasm_model_preset=preset.setdefault("cyto_model_name",'cyto3'),
79
- cytoplasm_channel_preset=preset.setdefault("cytoplasm channel",0),
80
- cyto_diameter_preset=preset.setdefault("cytoplasm diameter",180),
81
- nucleus_model_preset=preset.setdefault("nucleus_model_name",'nuclei'),
82
- nucleus_channel_preset=preset.setdefault("nucleus channel",0),
83
- nucleus_diameter_preset=preset.setdefault("nucleus diameter",150),
84
- segment_only_nuclei_preset=preset.setdefault("Segment only nuclei",False)
88
+ multichannel=True,
89
+ is_3D_stack=True,
90
+ cytoplasm_model_preset=preset.setdefault("cyto_model_name",default.CYTO_MODEL),
91
+ cytoplasm_channel_preset=preset.setdefault("cytoplasm_channel",default.CHANNEL),
92
+ cyto_diameter_preset=preset.setdefault("cytoplasm_diameter",default.CYTO_DIAMETER),
93
+ nucleus_model_preset=preset.setdefault("nucleus_model_name",default.NUC_MODEL),
94
+ nucleus_channel_preset=preset.setdefault("nucleus channel",default.CHANNEL),
95
+ nucleus_diameter_preset=preset.setdefault("nucleus_diameter",default.NUC_DIAMETER),
96
+ segment_only_nuclei_preset=preset.setdefault("segment_only_nuclei",default.SEGMENT_ONLY_NUCLEI),
85
97
  )
86
98
 
87
99
  apply_segmentation_button = sg.Button('apply', key='apply-segmentation')
88
100
  segmentation_layout += [[apply_segmentation_button]]
89
- seg_keys_to_hide = ['show segmentation', 'saving path', 'filename', 'other_nucleus_image']
101
+ seg_keys_to_hide = ['show_segmentation', 'saving path', 'filename', 'other_nucleus_image', 'save_segmentation_visual', 'saving path_browse']
90
102
  segmentation_tab = sg.Tab("Segmentation", segmentation_layout, visible=False)
91
103
 
92
104
  #Detection tab
@@ -100,13 +112,14 @@ def batch_promp(
100
112
  )
101
113
  apply_detection_button = sg.Button('apply', key='apply-detection')
102
114
  detection_layout += [[apply_detection_button]]
103
- detection_keys_to_hide = ['do_spots_csv', 'do_spots_excel', 'do_spots_feather','spots_filename','spots_extraction_folder']
115
+ detection_keys_to_hide = ['do_spots_csv', 'do_spots_excel', 'spots_filename','spots_extraction_folder', 'spots_extraction_folder_browse']
104
116
  detection_tab = sg.Tab("Detection", detection_layout, visible=False)
105
117
 
106
118
  #Output tab
107
119
  show_batch_folder_text = sg.Text('', key= 'batch_folder_text')
108
120
  apply_output_button = sg.Button('apply', key='apply-output')
109
- save_segmentation_box = sg.Checkbox("save segmentation", disabled=True, key='save segmentation')
121
+ save_segmentation_visual_box = sg.Checkbox("save segmentation", disabled=True, key='save segmentation', tooltip= "Save png files illustrating segmentation borders.")
122
+ save_segmentation_masks_box = sg.Check("save labels", disabled=True, key="save_masks", tooltip= "Save segmentation labels as .npy files.")
110
123
  save_detection_box = sg.Checkbox("create spot detection visuals", key= 'save detection', tooltip="Create multichannel tiff with raw spot signal and detected spots.\nWarning if processing a lot of files make sure you have enough free space on your hard drive.")
111
124
  extract_spots_box = sg.Checkbox("extract spots", key='extract spots')
112
125
  batch_name_input = sg.InputText(size=25, key='batch_name')
@@ -115,13 +128,16 @@ def batch_promp(
115
128
  [show_batch_folder_text],
116
129
  [sg.Text("Select a folder : "), sg.FolderBrowse(initial_folder=os.getcwd(), key='output_folder', target=(1,-1))],
117
130
  [sg.Text("Name for batch : "), batch_name_input],
118
- [save_segmentation_box],
119
131
  [save_detection_box],
120
132
  [extract_spots_box],
121
133
  [sg.Text("Data extension", font=('bold',15), pad=(0,10))],
122
- [sg.Checkbox(".csv", key='csv'),sg.Checkbox(".xlsx", key='xlsx'),sg.Checkbox(".feather", key='feather'),],
134
+ [sg.Checkbox(".csv", key='csv'),sg.Checkbox(".xlsx", key='xlsx')],
135
+ [sg.Text("Segmentation", font=('bold',15), pad=(0,10))],
136
+ [save_segmentation_visual_box],
137
+ [save_segmentation_masks_box],
123
138
  [apply_output_button],
124
139
  ]
140
+
125
141
  output_tab = sg.Tab("Output", output_layout, visible=True)
126
142
 
127
143
  ##TAB GROUP
@@ -129,9 +145,10 @@ def batch_promp(
129
145
  tab_col = sg.Column( #Allow the tab to be scrollable
130
146
  [[_tab_group]],
131
147
  scrollable=True,
132
- vertical_scroll_only=True,
148
+ vertical_scroll_only=False,
133
149
  s= (390,390),
134
- pad=((0,0),(5,5))
150
+ pad=((0,0),(5,5)),
151
+ expand_x=True,
135
152
  )
136
153
 
137
154
  tab_dict= {
@@ -172,14 +189,14 @@ def batch_promp(
172
189
  #########################################
173
190
  ##### Window Creation
174
191
  #########################################
175
- stream_output = sg.Output(size=(100,10), pad=(30,10), visible=True)
192
+ stream_output = sg.Output(size=(100,10), pad=(30,10), visible=True, expand_x=True, expand_y=True)
176
193
  layout = [
177
194
  [sg.Text("Batch Processing", font=('bold',20), pad=((300,0),(0,2)))],
178
195
  [sg.Text("Select a folder : "), sg.FolderBrowse(initial_folder=os.getcwd(), key='Batch_folder'), sg.Button('Load')],
179
196
  [files_table],
180
197
  [sanity_header, sanity_check_button, sanity_progress],
181
198
  [dimension_number_text],
182
- [tab_col, launch_col],
199
+ [tab_col, sg.Push(), launch_col, sg.Push()],
183
200
  [stream_output],
184
201
  ]
185
202
 
@@ -227,6 +244,8 @@ def batch_promp(
227
244
  timeout = 500
228
245
  print("Welcome to small fish batch analysis. Please start by loading some files and setting parameters.")
229
246
 
247
+ if values is None : return results_df, cell_results_df, acquisition_id, preset, False, None,None
248
+
230
249
  batch_folder = values.get('Batch_folder')
231
250
  is_multichanel = values.get('is_multichannel')
232
251
  is_3D = values.get('is_3D_stack')
@@ -386,6 +405,7 @@ def batch_promp(
386
405
  segmentation_correct_text= segmentation_ok_text,
387
406
  do_segmentation=do_segmentation,
388
407
  is_multichannel=is_multichanel,
408
+ is_3D=is_3D,
389
409
  is_mapping_ok=Master_parameters_dict['_is_mapping_correct']
390
410
  )
391
411
 
@@ -422,7 +442,5 @@ def batch_promp(
422
442
  except Exception as e :
423
443
  stream_output.restore_stderr()
424
444
  stream_output.restore_stdout()
425
- raise e
426
-
427
-
428
- window.close()
445
+ window.close()
446
+ raise e
@@ -87,15 +87,26 @@ def update_detection_tab(
87
87
 
88
88
  tab_elmt.update(visible=is_mapping_ok)
89
89
 
90
- def update_segmentation_tab(tab_elmt : sg.Tab, segmentation_correct_text : sg.Text, do_segmentation, is_multichannel, is_mapping_ok) :
90
+ def update_segmentation_tab(
91
+ tab_elmt : sg.Tab,
92
+ segmentation_correct_text : sg.Text,
93
+ do_segmentation : bool,
94
+ is_multichannel : bool,
95
+ is_3D : bool,
96
+ is_mapping_ok: bool
97
+ ) :
91
98
 
92
99
  #Access elements
93
- cytoplasm_channel_elmt = get_elmt_from_key(tab_elmt, key= 'cytoplasm channel')
94
- nucleus_channel_elmt = get_elmt_from_key(tab_elmt, key= 'nucleus channel')
100
+ cytoplasm_channel_elmt = get_elmt_from_key(tab_elmt, key= 'cytoplasm_channel')
101
+ nucleus_channel_elmt = get_elmt_from_key(tab_elmt, key= 'nucleus_channel')
102
+ do_nucleus_3D_elmt = get_elmt_from_key(tab_elmt, key= "nucleus_segmentation_3D")
103
+ do_cytoplasm_3D_elmt = get_elmt_from_key(tab_elmt, key= "cytoplasm_segmentation_3D")
95
104
 
96
105
  #Update values
97
106
  cytoplasm_channel_elmt.update(disabled = not is_multichannel)
98
107
  nucleus_channel_elmt.update(disabled = not is_multichannel)
108
+ do_nucleus_3D_elmt.update(disabled = not is_3D)
109
+ do_cytoplasm_3D_elmt.update(disabled = not is_3D)
99
110
  segmentation_correct_text.update(visible= do_segmentation)
100
111
 
101
112
  tab_elmt.update(visible=is_mapping_ok and do_segmentation)
@@ -126,7 +137,12 @@ def update_output_tab(
126
137
  do_segmentation,
127
138
  output_folder,
128
139
  ) :
140
+
141
+ #Segmentation
129
142
  segmentation_box = get_elmt_from_key(tab_elmt, "save segmentation")
130
143
  segmentation_box.update(disabled = not do_segmentation)
144
+ segmentation_save_masks_elmt = get_elmt_from_key(tab_elmt, "save_masks")
145
+ segmentation_save_masks_elmt.update(disabled = not do_segmentation)
146
+
131
147
  batch_folder_text = get_elmt_from_key(tab_elmt, "batch_folder_text")
132
148
  batch_folder_text.update(value = output_folder)
@@ -64,3 +64,5 @@ def create_map(
64
64
 
65
65
  return maping
66
66
 
67
+ def clean_filename(filename : str) :
68
+ return "_".join(filename.split('.')[:-1])
@@ -15,13 +15,13 @@ z
15
15
  c
16
16
  t
17
17
  cyto_model_name
18
- cytoplasm channel
19
- cytoplasm diameter
18
+ cytoplasm_channel
19
+ cytoplasm_diameter
20
20
  nucleus_model_name
21
21
  nucleus channel
22
- nucleus diameter
23
- Segment only nuclei
24
- show segmentation
22
+ nucleus_diameter
23
+ segment_only_nuclei
24
+ show_segmentation
25
25
  saving path
26
26
  filename
27
27
  threshold
@@ -0,0 +1,51 @@
1
+ """"
2
+ Constant submodule to have a common reference for parameters default values
3
+ """
4
+ import os
5
+
6
+ #Image
7
+ IS_MULTICHANNEL = False
8
+ IS_3D_STACK = False
9
+ CHANNEL = 0
10
+ NUC_CHANNEL = 1
11
+
12
+ #Segmentation
13
+ FLOW_THRESHOLD = 0.4
14
+ CELLPROB_THRESHOD = 0.
15
+ CYTO_MODEL = "cpsam"
16
+ NUC_MODEL = "cpsam"
17
+ CYTO_DIAMETER = 90
18
+ NUC_DIAMETER = 60
19
+ ANISOTROPY = 1.
20
+ SHOW_SEGMENTATION = True
21
+ SEGMENT_ONLY_NUCLEI = False
22
+ DO_3D_SEMGENTATION = False
23
+ VISUAL_PATH = os.getcwd()
24
+ SAVE_SEGMENTATION_VISUAL = False
25
+
26
+ #Detection
27
+ THRESHOLD = None
28
+ THRESHOLD_PENALTY = 1
29
+ DO_DENSE_REGIONS_DECONVOLUTION = False
30
+ DO_CLUSTER_COMPUTATION = False
31
+ DO_CLUSTER_COMPUTATION = False
32
+ SHOW_NAPARI_CORRECTOR = True
33
+ INTERACTIVE_THRESHOLD = False
34
+
35
+ #Deconvolution
36
+ ALPHA = 0.5
37
+ BETA = 1.
38
+ GAMMA = 3.
39
+
40
+ #Clustering
41
+ CLUSTER_SIZE = 400
42
+ MIN_NUMBER_SPOTS = 5
43
+
44
+ #Coloc
45
+ COLOC_RANGE = 400
46
+ COLOC_VOXEL_SIZE = (1,2,3)
47
+
48
+ #Spots Extraction
49
+ DO_CSV = False
50
+ DO_EXCEL = False
51
+ SPOT_EXTRACTION_FOLDER = os.getcwd()
@@ -24,4 +24,6 @@ from .layout import tuple_layout
24
24
  from .layout import radio_layout
25
25
  from .layout import add_header
26
26
 
27
- from .animation import add_default_loading
27
+ from .animation import add_default_loading
28
+
29
+ from .theme import default_theme