small-fish-gui 1.0.0__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.
@@ -0,0 +1,80 @@
1
+ #### New version for main.py
2
+ import pandas as pd
3
+ import PySimpleGUI as sg
4
+ from ..gui import hub_prompt
5
+ from .actions import add_detection, save_results, compute_colocalisation
6
+
7
+ #'Global' parameters
8
+ user_parameters = dict() # Very important object containg all choice from user that will influence the behavior of the main loop.
9
+ acquisition_id = -1
10
+ result_df = pd.DataFrame()
11
+ cell_result_df = pd.DataFrame()
12
+ coloc_df = pd.DataFrame()
13
+ segmentation_done = False
14
+ cytoplasm_label = None
15
+ nucleus_label = None
16
+
17
+ while True : #Break this loop to close small_fish
18
+ try :
19
+ event, values = hub_prompt(result_df, segmentation_done)
20
+
21
+ if event == 'Add detection' :
22
+
23
+ new_result_df, new_cell_result_df, acquisition_id, user_parameters, segmentation_done, cytoplasm_label, nucleus_label = add_detection(
24
+ user_parameters=user_parameters,
25
+ segmentation_done=segmentation_done,
26
+ acquisition_id=acquisition_id,
27
+ cytoplasm_label = cytoplasm_label,
28
+ nucleus_label = nucleus_label,
29
+ )
30
+ result_df = pd.concat([result_df, new_result_df], axis=0)
31
+ cell_result_df = pd.concat([cell_result_df, new_cell_result_df], axis=0)
32
+
33
+ elif event == 'Save results' :
34
+ save_results(
35
+ result_df=result_df,
36
+ cell_result_df=cell_result_df,
37
+ coloc_df=coloc_df
38
+ )
39
+
40
+ elif event == 'Compute colocalisation' :
41
+ result_tables = values.setdefault('result_table', []) #Contains the lines selected by the user on the sum-up array.
42
+
43
+ res_coloc= compute_colocalisation(
44
+ result_tables,
45
+ result_dataframe=result_df
46
+ )
47
+
48
+ coloc_df = pd.concat(
49
+ [coloc_df,res_coloc],
50
+ axis= 0)
51
+
52
+ elif event == "Reset results" :
53
+ result_df = pd.DataFrame()
54
+ cell_result_df = pd.DataFrame()
55
+ coloc_df = pd.DataFrame()
56
+ acquisition_id = -1
57
+ segmentation_done = False
58
+ cytoplasm_label = None
59
+ nucleus_label = None
60
+
61
+ elif event == "Reset segmentation" :
62
+ segmentation_done = False
63
+ cytoplasm_label = None
64
+ nucleus_label = None
65
+
66
+ elif event == "Delete acquisitions" :
67
+ #TODO
68
+ pass
69
+
70
+ elif event == "Batch detection" :
71
+ #TODO
72
+ pass
73
+
74
+ else :
75
+ break
76
+
77
+ except Exception as error :
78
+ sg.popup(str(error))
79
+ raise error
80
+ quit()
@@ -0,0 +1,116 @@
1
+ def yielder(n) :
2
+ for i in range(n) :
3
+ yield i
4
+
5
+ def constructor(n) :
6
+ def inner() :
7
+ return yielder(n)
8
+ return inner
9
+
10
+ #test
11
+
12
+ N = 10
13
+
14
+ gen1 = yielder(N)
15
+
16
+ a = constructor(10)
17
+
18
+ print(type(a))
19
+
20
+ gen2 = a()
21
+ gen3 = a()
22
+
23
+ print('gen1 : ', list(gen1))
24
+ print('gen2 : ', list(gen2))
25
+ print('gen3 : ', list(gen3))
26
+ print('gen3 : ', list(gen3))
27
+
28
+
29
+ #Napari test
30
+
31
+ import napari
32
+ import numpy as np
33
+ from napari.utils.events import Event
34
+ from napari.layers import Points
35
+
36
+ seed = 0
37
+ points_number = 500
38
+ rand_gen = np.random.default_rng(seed=seed)
39
+
40
+ im_shape = (10,1000,1000)
41
+ scale = (1,1,1)
42
+
43
+ im = np.zeros(shape=im_shape)
44
+
45
+ points = np.array(
46
+ list(zip(
47
+ rand_gen.integers(0,im_shape[0],size=points_number), #Z
48
+ rand_gen.integers(0,im_shape[1],size=points_number), #Y
49
+ rand_gen.integers(0,im_shape[2],size=points_number), #X
50
+ )),
51
+ dtype= int
52
+ )
53
+
54
+ spots_number = rand_gen.integers(0,20,points_number, dtype=int)
55
+ id_list = np.arange(points_number)
56
+
57
+ Viewer = napari.Viewer(title= "test", show=False)
58
+ Viewer.add_image(im),
59
+ cluster_layer = Viewer.add_points(
60
+ points,
61
+ size = 10,
62
+ scale=scale,
63
+ face_color= 'blue',
64
+ opacity= 0.7,
65
+ symbol= 'diamond',
66
+ name= 'foci',
67
+ features= {"spot_number" : spots_number, "id" : id_list},
68
+ feature_defaults= {"spot_number" : 0, "id" : -1})
69
+
70
+
71
+ class Points_callback :
72
+ """
73
+ Custom class to handle points number evolution during Napari run.
74
+ """
75
+
76
+ def __init__(self, points, next_id) -> None:
77
+ self.points = points
78
+ self.next_id = next_id
79
+ self._set_callback()
80
+
81
+ def __str__(self) -> str:
82
+ string = 'Points_callback object state :\ncurrent_points_number : {0}\ncurrnet_id : {1}'.format(self.current_points_number, self.next_id)
83
+ return string
84
+
85
+ def get_points(self) :
86
+ return self.points
87
+
88
+ def get_next_id(self) :
89
+ return self.next_id
90
+
91
+ def _set_callback(self) :
92
+ def callback(event:Event) :
93
+
94
+ old_points = self.get_points()
95
+ new_points:Points = event.source.data
96
+ features = event.source.features
97
+
98
+ current_point_number = len(old_points)
99
+ next_id = self.get_next_id()
100
+ new_points_number = len(new_points)
101
+
102
+ if new_points_number > current_point_number :
103
+ features.at[new_points_number - 1, "id"] = next_id
104
+ self.next_id += 1
105
+
106
+ #preparing next callback
107
+ self.points = new_points
108
+ self._set_callback()
109
+ self.callback = callback
110
+
111
+ live_points_number = len(points)
112
+ next_point_id = id_list[-1] + 1
113
+ _callback = Points_callback(points=points, next_id=next_point_id)
114
+ Viewer.show(block=False)
115
+ points_callback = Viewer.layers[1].events.data.connect((_callback, 'callback'))
116
+ napari.run()
@@ -0,0 +1,7 @@
1
+ import sys
2
+
3
+ def main():
4
+ import small_fish.pipeline.main
5
+
6
+ if __name__ == "__main__":
7
+ sys.exit(main())
@@ -0,0 +1,55 @@
1
+ import inspect
2
+
3
+ def check_parameter(**kwargs):
4
+ """Check dtype of the function's parameters.
5
+
6
+ Parameters
7
+ ----------
8
+ kwargs : Type or Tuple[Type]
9
+ Map of each parameter with its expected dtype.
10
+
11
+ Returns
12
+ -------
13
+ _ : bool
14
+ Assert if the array is well formatted.
15
+
16
+ """
17
+ # get the frame and the parameters of the function
18
+ frame = inspect.currentframe().f_back
19
+ _, _, _, values = inspect.getargvalues(frame)
20
+
21
+ # compare each parameter with its expected dtype
22
+ for arg in kwargs:
23
+ expected_dtype = kwargs[arg]
24
+ parameter = values[arg]
25
+ if not isinstance(parameter, expected_dtype):
26
+ actual = "'{0}'".format(type(parameter).__name__)
27
+ if isinstance(expected_dtype, tuple):
28
+ target = ["'{0}'".format(x.__name__) for x in expected_dtype]
29
+ target = "(" + ", ".join(target) + ")"
30
+ else:
31
+ target = expected_dtype.__name__
32
+ raise TypeError("Parameter {0} should be a {1}. It is a {2} "
33
+ "instead.".format(arg, target, actual))
34
+
35
+ return True
36
+
37
+
38
+ def compute_anisotropy_coef(voxel_size) :
39
+ """
40
+ Returns tuple (anisotropy_z, anisotropy_y, 1)
41
+ voxel_size : tuple (z,y,x).
42
+ """
43
+
44
+ if not isinstance(voxel_size, (tuple, list)) : raise TypeError("Expected voxel_size tuple or list")
45
+ if len(voxel_size) == 2 : is_3D = False
46
+ elif len(voxel_size) == 3 : is_3D = True
47
+ else : raise ValueError("Expected 2D or 3D voxel, {0} element(s) found".format(len(voxel_size)))
48
+
49
+ if is_3D :
50
+ z_anisotropy = voxel_size[0] / voxel_size [2]
51
+ xy_anisotropy = voxel_size[1] / voxel_size [2]
52
+ return (z_anisotropy, xy_anisotropy, 1)
53
+
54
+ else :
55
+ return (voxel_size[0] / voxel_size[1], 1)
@@ -0,0 +1,57 @@
1
+ Metadata-Version: 2.3
2
+ Name: small_fish_gui
3
+ Version: 1.0.0
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
+ Project-URL: Homepage, https://github.com/2Echoes/small_fish
6
+ Project-URL: Issues, https://github.com/2Echoes/small_fish/issues
7
+ Author-email: Slimani Floric <floric.slimani@live.com>
8
+ License-File: LICENSE
9
+ Classifier: License :: OSI Approved :: BSD License
10
+ Classifier: Operating System :: OS Independent
11
+ Classifier: Programming Language :: Python :: 3
12
+ Requires-Python: >=3.8
13
+ Description-Content-Type: text/markdown
14
+
15
+ # Small Fish
16
+ **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.
17
+
18
+ Cell segmentation is peformed using *cellpose* (published work) : https://github.com/MouseLand/cellpose
19
+
20
+ Spot detection is performed via *big-fish* (published work) : https://github.com/fish-quant/big-fish
21
+
22
+ Time stacks are not yet supported.
23
+
24
+ ## Installation
25
+
26
+ 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.
27
+
28
+ ```bash
29
+ conda create -n small_fish python=3.8
30
+ activate small_fish
31
+ ```
32
+ Then download the small_fish package :
33
+ ```bash
34
+ pip install small_fish
35
+ ```
36
+ <b> (Recommended) </b> Results visualisation is achieved through *Napari* which you can install with :
37
+
38
+ ```bash
39
+ pip install napari[all]
40
+ ```
41
+
42
+ ## Run Small fish
43
+
44
+ First activate your python environnement :
45
+ ```bash
46
+ activate small_fish
47
+ ```
48
+ Then launch Small fish :
49
+ ```bash
50
+ python -m small_fish
51
+ ```
52
+ ## Developpement
53
+
54
+ Optional features to include in future versions :
55
+ - batch processing
56
+ - time stack (which would include cell tracking)
57
+ - 3D segmentation
@@ -0,0 +1,32 @@
1
+ small_fish_gui/__init__.py,sha256=aAh4brM-eTSnFOWpYSFgMIqJzbjJX45RHIWi7ppl_nA,1941
2
+ small_fish_gui/__main__.py,sha256=scEcvIpJ4F5uvHnKycg4vPjXXQv4gjkf4FL5MyLxeUs,460
3
+ small_fish_gui/start.py,sha256=HTbzsVcaMji1BZnWyjfn3bDGIQeXGG4zFzvCBepqFvA,108
4
+ small_fish_gui/utils.py,sha256=tSoMb8N69WdKTtMItPb1DYZiIAz1mjI26BCKJAi6vuc,1798
5
+ small_fish_gui/gui/__init__.py,sha256=178HC3t2z4EnP0iBnMcaP_pyh5xHwOkEE6p3WJwBQeU,911
6
+ small_fish_gui/gui/animation.py,sha256=6_Y15_NzJ_TYBYseu3sSKaVkYRp2UCsVClAWOk3dESY,714
7
+ small_fish_gui/gui/general_help_screenshot.png,sha256=X4E6Td5f04K-pBUPDaBJRAE3D5b8fuEdiAUKhkIDr-0,54210
8
+ small_fish_gui/gui/help_module.py,sha256=pVSpGwhkI3bNr1EgBjnd-SukPTx6wcuFnAyyVNMZmWo,9608
9
+ small_fish_gui/gui/layout.py,sha256=E_Z87S1YUR1gx2447OM0156dKXbzMA_q9joCO4hsZd8,7644
10
+ small_fish_gui/gui/mapping_help_screenshot.png,sha256=HcuRh5TYciUogUasza5vZ_QSshaiHsskQK23mh9vQS8,34735
11
+ small_fish_gui/gui/prompts.py,sha256=mlw9NT5k3I8kTMB7w6W6QETbSIav_A7RhCmMVD7NFV0,12279
12
+ small_fish_gui/gui/segmentation_help_screenshot.png,sha256=rbSgIydT0gZtfMh1qk4mdMbEIyCaakvHmxa2eOrLwO0,118944
13
+ small_fish_gui/gui/test.py,sha256=Pf-GW9AgW-0VL1mFbYtqRvPAaa8DgwCThv2dDUHCcmU,156
14
+ small_fish_gui/interface/__init__.py,sha256=PB86R4Y9kV80aGZ-vP0ZW2KeaCwGbBbCtFCmbN2yl28,275
15
+ small_fish_gui/interface/image.py,sha256=X1L7S5svxUwdoDcI3QM1PbN-c4Nz5w30hixq3IgqSn8,1130
16
+ small_fish_gui/interface/output.py,sha256=wqXJHk-PzqZwYr8NHLg9jcEJlZQXZk8R76aeWcTxsEw,1337
17
+ small_fish_gui/interface/parameters.py,sha256=lUugD-4W2TZyJF3TH1q70TlktEYhhPtcPCrvxm5Dk50,36
18
+ small_fish_gui/interface/testing.py,sha256=MY5-GcPOUHagcrwR8A7QOjAmjZIDVC8Wz3NibLe3KQw,321
19
+ small_fish_gui/pipeline/_colocalisation.py,sha256=-zz_kvghpMSaBhQT0moHvwC6ee92S-oq-j9qZWqgZMY,9677
20
+ small_fish_gui/pipeline/_custom_errors.py,sha256=tQ-AUhgzIFpK30AZiQQrtHCHyGVRDdAoIjzL0Fk-1pA,43
21
+ small_fish_gui/pipeline/_detection_visualisation.py,sha256=CNxCQpiCzC9Uk-2RqSuTp55Glf1URCL_s8zidwljY9Y,5774
22
+ small_fish_gui/pipeline/_preprocess.py,sha256=AlB86KuCA0UKA0XbTgXTJbg92Az34hzba_hsVs-uZl0,10035
23
+ small_fish_gui/pipeline/_segmentation.py,sha256=IaeqsjwIweKH9LEm6qbDqssGW7R0MRZSh7PtF4etIEI,12772
24
+ small_fish_gui/pipeline/_signaltonoise.py,sha256=7A9t7xu7zghI6cr201Ldm-LjJ5NOuP56VSeJ8KIzcUo,8497
25
+ small_fish_gui/pipeline/actions.py,sha256=n6lr_LqV4PT5uw6KfovehUuUK-yTJ66G-IhY2uhHF_k,5472
26
+ small_fish_gui/pipeline/detection.py,sha256=l4G2UHJmrzIg_alAge2GY0h5D34N_oqWzfgjfe2SI04,26032
27
+ small_fish_gui/pipeline/main.py,sha256=4_Qk-NRhjOEsgN7T35NXOHj4OdDmZGS5kVeKde-yCiI,2593
28
+ small_fish_gui/pipeline/test.py,sha256=w4ZMGDmUDXxVgWTlZ2TKw19W8q5gcE9gLMKe0SWnRrw,2827
29
+ small_fish_gui-1.0.0.dist-info/METADATA,sha256=1E3_IdeRT3wf_hl4DRqWssW-DfF1UBwl9TgAilhfOjs,1991
30
+ small_fish_gui-1.0.0.dist-info/WHEEL,sha256=zEMcRr9Kr03x1ozGwg5v9NQBKn3kndp6LSoSlVg-jhU,87
31
+ small_fish_gui-1.0.0.dist-info/licenses/LICENSE,sha256=-iFy8VGBYs5VsHglKpk4D-hxqQ2jMJaqmfq_ulIzDks,1303
32
+ small_fish_gui-1.0.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.24.2
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,24 @@
1
+ BSD 2-Clause License
2
+
3
+ Copyright (c) 2023, Floric Slimani
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ 1. Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ 2. Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.