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.
- small_fish_gui/README.md +42 -70
- small_fish_gui/__init__.py +1 -1
- small_fish_gui/__main__.py +1 -1
- small_fish_gui/batch/integrity.py +8 -1
- small_fish_gui/batch/output.py +16 -0
- small_fish_gui/batch/pipeline.py +43 -24
- small_fish_gui/batch/prompt.py +44 -26
- small_fish_gui/batch/update.py +19 -3
- small_fish_gui/batch/utils.py +2 -0
- small_fish_gui/batch/values.txt +5 -5
- small_fish_gui/default_values.py +51 -0
- small_fish_gui/gui/__init__.py +3 -1
- small_fish_gui/gui/_napari_widgets.py +15 -4
- small_fish_gui/gui/layout.py +123 -54
- small_fish_gui/gui/napari_visualiser.py +12 -8
- small_fish_gui/gui/prompts.py +61 -74
- small_fish_gui/gui/tooltips.py +15 -0
- small_fish_gui/hints.py +23 -4
- small_fish_gui/illustrations/DetectionVitrine_filtre.png +0 -0
- small_fish_gui/illustrations/DetectionVitrine_signal.png +0 -0
- small_fish_gui/illustrations/FocciVitrine.png +0 -0
- small_fish_gui/illustrations/FocciVitrine_no_spots.png +0 -0
- small_fish_gui/illustrations/Segmentation2D.png +0 -0
- small_fish_gui/illustrations/Segmentation2D_with_labels.png +0 -0
- small_fish_gui/logo.png +0 -0
- small_fish_gui/{pipeline/main.py → main_menu.py} +16 -15
- small_fish_gui/pipeline/_colocalisation.py +60 -41
- small_fish_gui/pipeline/_preprocess.py +13 -12
- small_fish_gui/pipeline/actions.py +102 -14
- small_fish_gui/pipeline/detection.py +5 -1
- small_fish_gui/pipeline/segmentation.py +206 -73
- small_fish_gui/pipeline/spots.py +129 -5
- small_fish_gui/pipeline/testing.ipynb +1571 -2
- small_fish_gui/requirements.txt +4 -4
- {small_fish_gui-1.10.4.dist-info → small_fish_gui-2.0.1.dist-info}/METADATA +14 -16
- small_fish_gui-2.0.1.dist-info/RECORD +59 -0
- small_fish_gui-1.10.4.dist-info/RECORD +0 -49
- {small_fish_gui-1.10.4.dist-info → small_fish_gui-2.0.1.dist-info}/WHEEL +0 -0
- {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
|
-
|
|
3
|
+
[](https://opensource.org/licenses/BSD-2-Clause)
|
|
4
|
+
[](https://github.com/SmallFishGUI/small_fish_gui) [](https://www.python.org/downloads/)
|
|
5
5
|
|
|
6
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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/)
|
|
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
|
-
|
|
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.
|
small_fish_gui/__init__.py
CHANGED
|
@@ -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__ = "
|
|
40
|
+
__version__ = "2.0.1"
|
|
41
41
|
__wiki__ = "https://github.com/2Echoes/small_fish_gui/wiki"
|
|
42
42
|
|
|
43
43
|
import os
|
small_fish_gui/__main__.py
CHANGED
|
@@ -63,11 +63,18 @@ def check_channel_map_integrity(
|
|
|
63
63
|
) :
|
|
64
64
|
|
|
65
65
|
#Check integrity
|
|
66
|
-
|
|
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)
|
small_fish_gui/batch/pipeline.py
CHANGED
|
@@ -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['
|
|
105
|
+
cyto_diameter= parameters['cytoplasm_diameter'],
|
|
104
106
|
nucleus_model_name= parameters['nucleus_model_name'],
|
|
105
|
-
nucleus_diameter= parameters['
|
|
106
|
-
channels=[parameters['
|
|
107
|
-
|
|
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['
|
|
129
|
+
cyto_image=im_seg[parameters['cytoplasm_channel']],
|
|
121
130
|
cyto_label= cytoplasm_label,
|
|
122
|
-
nuc_image= im_seg[parameters['
|
|
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['
|
|
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['
|
|
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
|
-
|
|
261
|
-
|
|
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
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
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
|
-
|
|
287
|
+
error_log.writelines(log)
|
|
269
288
|
|
|
270
289
|
print("Ignoring current acquisition and proceeding to next one.")
|
|
271
290
|
continue
|
small_fish_gui/batch/prompt.py
CHANGED
|
@@ -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(
|
|
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" ,
|
|
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" ,
|
|
51
|
-
do_dense_regions_deconvolution_preset=preset.setdefault("do_dense_regions_deconvolution"
|
|
52
|
-
do_clustering_preset= preset.setdefault("do_cluster_computation",
|
|
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
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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 = ['
|
|
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', '
|
|
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
|
-
|
|
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')
|
|
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=
|
|
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
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
window.close()
|
|
445
|
+
window.close()
|
|
446
|
+
raise e
|
small_fish_gui/batch/update.py
CHANGED
|
@@ -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(
|
|
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= '
|
|
94
|
-
nucleus_channel_elmt = get_elmt_from_key(tab_elmt, key= '
|
|
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)
|
small_fish_gui/batch/utils.py
CHANGED
small_fish_gui/batch/values.txt
CHANGED
|
@@ -15,13 +15,13 @@ z
|
|
|
15
15
|
c
|
|
16
16
|
t
|
|
17
17
|
cyto_model_name
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
cytoplasm_channel
|
|
19
|
+
cytoplasm_diameter
|
|
20
20
|
nucleus_model_name
|
|
21
21
|
nucleus channel
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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()
|
small_fish_gui/gui/__init__.py
CHANGED