spacr 0.1.12__tar.gz → 0.1.50__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.
- {spacr-0.1.12/spacr.egg-info → spacr-0.1.50}/PKG-INFO +13 -26
- {spacr-0.1.12 → spacr-0.1.50}/README.rst +10 -19
- {spacr-0.1.12 → spacr-0.1.50}/setup.py +40 -24
- {spacr-0.1.12 → spacr-0.1.50}/spacr/app_annotate.py +2 -3
- spacr-0.1.50/spacr/app_classify.py +8 -0
- {spacr-0.1.12 → spacr-0.1.50}/spacr/app_make_masks.py +1 -2
- {spacr-0.1.12 → spacr-0.1.50}/spacr/app_make_masks_v2.py +2 -4
- spacr-0.1.50/spacr/app_mask.py +8 -0
- spacr-0.1.50/spacr/app_measure.py +8 -0
- {spacr-0.1.12 → spacr-0.1.50}/spacr/deep_spacr.py +3 -1
- {spacr-0.1.12 → spacr-0.1.50}/spacr/gui.py +26 -16
- spacr-0.1.50/spacr/gui_utils.py +1525 -0
- {spacr-0.1.12 → spacr-0.1.50}/spacr/measure.py +24 -3
- {spacr-0.1.12 → spacr-0.1.50}/spacr/settings.py +13 -2
- {spacr-0.1.12 → spacr-0.1.50}/spacr/utils.py +59 -5
- {spacr-0.1.12 → spacr-0.1.50/spacr.egg-info}/PKG-INFO +13 -26
- spacr-0.1.50/spacr.egg-info/entry_points.txt +8 -0
- {spacr-0.1.12 → spacr-0.1.50}/spacr.egg-info/requires.txt +2 -6
- spacr-0.1.12/spacr/app_classify.py +0 -201
- spacr-0.1.12/spacr/app_mask.py +0 -251
- spacr-0.1.12/spacr/app_measure.py +0 -248
- spacr-0.1.12/spacr/gui_utils.py +0 -1185
- spacr-0.1.12/spacr.egg-info/entry_points.txt +0 -9
- {spacr-0.1.12 → spacr-0.1.50}/LICENSE +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/MANIFEST.in +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/setup.cfg +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/spacr/__init__.py +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/spacr/__main__.py +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/spacr/chris.py +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/spacr/core.py +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/spacr/graph_learning.py +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/spacr/io.py +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/spacr/logger.py +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/spacr/models/cp/toxo_plaque_cyto_e25000_X1120_Y1120.CP_model +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/spacr/models/cp/toxo_plaque_cyto_e25000_X1120_Y1120.CP_model_settings.csv +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/spacr/models/cp/toxo_pv_lumen.CP_model +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/spacr/plot.py +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/spacr/sequencing.py +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/spacr/sim.py +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/spacr/sim_app.py +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/spacr/timelapse.py +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/spacr/version.py +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/spacr.egg-info/SOURCES.txt +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/spacr.egg-info/dependency_links.txt +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/spacr.egg-info/top_level.txt +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/tests/test_annotate_app.py +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/tests/test_core.py +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/tests/test_gui_classify_app.py +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/tests/test_gui_mask_app.py +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/tests/test_gui_measure_app.py +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/tests/test_gui_sim_app.py +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/tests/test_gui_utils.py +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/tests/test_io.py +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/tests/test_mask_app.py +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/tests/test_measure.py +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/tests/test_plot.py +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/tests/test_sim.py +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/tests/test_timelapse.py +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/tests/test_train.py +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/tests/test_umap.py +0 -0
- {spacr-0.1.12 → spacr-0.1.50}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: spacr
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.50
|
4
4
|
Summary: Spatial phenotype analysis of crisp screens (SpaCr)
|
5
5
|
Home-page: https://github.com/EinarOlafsson/spacr
|
6
6
|
Author: Einar Birnir Olafsson
|
@@ -9,7 +9,6 @@ Classifier: Programming Language :: Python :: 3
|
|
9
9
|
Classifier: License :: OSI Approved :: MIT License
|
10
10
|
Classifier: Operating System :: OS Independent
|
11
11
|
License-File: LICENSE
|
12
|
-
Requires-Dist: dgl==0.9.1
|
13
12
|
Requires-Dist: torch<3.0,>=2.2.1
|
14
13
|
Requires-Dist: torchvision<1.0,>=0.17.1
|
15
14
|
Requires-Dist: torch-geometric<3.0,>=2.5.1
|
@@ -40,12 +39,9 @@ Requires-Dist: ttf_opensans>=2020.10.30
|
|
40
39
|
Requires-Dist: customtkinter<6.0,>=5.2.2
|
41
40
|
Requires-Dist: biopython<2.0,>=1.80
|
42
41
|
Requires-Dist: lxml<6.0,>=5.1.0
|
43
|
-
Requires-Dist:
|
44
|
-
Requires-Dist: superqt<0.7,>=0.6.7
|
45
|
-
Requires-Dist: pyqt6<6.8,>=6.7.1
|
46
|
-
Requires-Dist: pyqtgraph<0.14,>=0.13.7
|
42
|
+
Requires-Dist: huggingface-hub<0.25,>=0.24.0
|
47
43
|
Provides-Extra: dev
|
48
|
-
Requires-Dist: pytest
|
44
|
+
Requires-Dist: pytest<3.11,>=3.9; extra == "dev"
|
49
45
|
Provides-Extra: headless
|
50
46
|
Requires-Dist: opencv-python-headless; extra == "headless"
|
51
47
|
Provides-Extra: full
|
@@ -67,7 +63,7 @@ Requires-Dist: opencv-python; extra == "full"
|
|
67
63
|
SpaCr
|
68
64
|
=====
|
69
65
|
|
70
|
-
Spatial phenotype analysis of CRISPR-Cas9 screens (SpaCr). The spatial organization of organelles and proteins within cells constitutes a key level of functional regulation. In the context of infectious disease, the spatial relationships between host cell structures and intracellular pathogens are critical to
|
66
|
+
Spatial phenotype analysis of CRISPR-Cas9 screens (SpaCr). The spatial organization of organelles and proteins within cells constitutes a key level of functional regulation. In the context of infectious disease, the spatial relationships between host cell structures and intracellular pathogens are critical to understanding host clearance mechanisms and how pathogens evade them. SpaCr is a Python-based software package for generating single-cell image data for deep-learning sub-cellular/cellular phenotypic classification from pooled genetic CRISPR-Cas9 screens. SpaCr provides a flexible toolset to extract single-cell images and measurements from high-content cell painting experiments, train deep-learning models to classify cellular/subcellular phenotypes, simulate, and analyze pooled CRISPR-Cas9 imaging screens.
|
71
67
|
|
72
68
|
Features
|
73
69
|
--------
|
@@ -76,9 +72,9 @@ Features
|
|
76
72
|
|
77
73
|
- **Object Measurements:** Measurements for each object including scikit-image-regionprops, intensity percentiles, shannon-entropy, pearsons and manders correlations, homogeneity, and radial distribution. Measurements are saved to a SQL database in object-level tables.
|
78
74
|
|
79
|
-
- **Crop Images:**
|
75
|
+
- **Crop Images:** Save objects (cells, nuclei, pathogen, cytoplasm) as images. Object image paths are saved in a SQL database.
|
80
76
|
|
81
|
-
- **Train CNNs or Transformers:** Train Torch
|
77
|
+
- **Train CNNs or Transformers:** Train Torch models to classify single object images.
|
82
78
|
|
83
79
|
- **Manual Annotation:** Supports manual annotation of single-cell images and segmentation to refine training datasets for training CNNs/Transformers or cellpose, respectively.
|
84
80
|
|
@@ -95,29 +91,20 @@ Features
|
|
95
91
|
Installation
|
96
92
|
------------
|
97
93
|
|
98
|
-
|
94
|
+
If using Windows, switch to Linux—it's free, open-source, and better.
|
99
95
|
|
100
|
-
|
101
|
-
~~~~~~
|
96
|
+
Before installing SpaCr on OSX ensure OpenMP is installed::
|
102
97
|
|
103
|
-
|
98
|
+
brew install libomp
|
104
99
|
|
105
|
-
(Tkinter is included with the standard Python installation on macOS
|
106
|
-
|
107
|
-
On Linux:
|
108
|
-
|
109
|
-
::
|
100
|
+
SpaCr GUI requires Tkinter. On Linux, ensure Tkinter is installed. (Tkinter is included with the standard Python installation on macOS and Windows)::
|
110
101
|
|
111
102
|
sudo apt-get install python3-tk
|
112
103
|
|
113
|
-
Install
|
114
|
-
|
115
|
-
::
|
104
|
+
Install SpaCr with pip::
|
116
105
|
|
117
106
|
pip install spacr
|
118
107
|
|
119
|
-
Run
|
120
|
-
|
121
|
-
::
|
108
|
+
Run SpaCr GUI::
|
122
109
|
|
123
|
-
|
110
|
+
spacr
|
@@ -14,7 +14,7 @@
|
|
14
14
|
SpaCr
|
15
15
|
=====
|
16
16
|
|
17
|
-
Spatial phenotype analysis of CRISPR-Cas9 screens (SpaCr). The spatial organization of organelles and proteins within cells constitutes a key level of functional regulation. In the context of infectious disease, the spatial relationships between host cell structures and intracellular pathogens are critical to
|
17
|
+
Spatial phenotype analysis of CRISPR-Cas9 screens (SpaCr). The spatial organization of organelles and proteins within cells constitutes a key level of functional regulation. In the context of infectious disease, the spatial relationships between host cell structures and intracellular pathogens are critical to understanding host clearance mechanisms and how pathogens evade them. SpaCr is a Python-based software package for generating single-cell image data for deep-learning sub-cellular/cellular phenotypic classification from pooled genetic CRISPR-Cas9 screens. SpaCr provides a flexible toolset to extract single-cell images and measurements from high-content cell painting experiments, train deep-learning models to classify cellular/subcellular phenotypes, simulate, and analyze pooled CRISPR-Cas9 imaging screens.
|
18
18
|
|
19
19
|
Features
|
20
20
|
--------
|
@@ -23,9 +23,9 @@ Features
|
|
23
23
|
|
24
24
|
- **Object Measurements:** Measurements for each object including scikit-image-regionprops, intensity percentiles, shannon-entropy, pearsons and manders correlations, homogeneity, and radial distribution. Measurements are saved to a SQL database in object-level tables.
|
25
25
|
|
26
|
-
- **Crop Images:**
|
26
|
+
- **Crop Images:** Save objects (cells, nuclei, pathogen, cytoplasm) as images. Object image paths are saved in a SQL database.
|
27
27
|
|
28
|
-
- **Train CNNs or Transformers:** Train Torch
|
28
|
+
- **Train CNNs or Transformers:** Train Torch models to classify single object images.
|
29
29
|
|
30
30
|
- **Manual Annotation:** Supports manual annotation of single-cell images and segmentation to refine training datasets for training CNNs/Transformers or cellpose, respectively.
|
31
31
|
|
@@ -42,29 +42,20 @@ Features
|
|
42
42
|
Installation
|
43
43
|
------------
|
44
44
|
|
45
|
-
|
45
|
+
If using Windows, switch to Linux—it's free, open-source, and better.
|
46
46
|
|
47
|
-
|
48
|
-
~~~~~~
|
47
|
+
Before installing SpaCr on OSX ensure OpenMP is installed::
|
49
48
|
|
50
|
-
|
49
|
+
brew install libomp
|
51
50
|
|
52
|
-
(Tkinter is included with the standard Python installation on macOS
|
53
|
-
|
54
|
-
On Linux:
|
55
|
-
|
56
|
-
::
|
51
|
+
SpaCr GUI requires Tkinter. On Linux, ensure Tkinter is installed. (Tkinter is included with the standard Python installation on macOS and Windows)::
|
57
52
|
|
58
53
|
sudo apt-get install python3-tk
|
59
54
|
|
60
|
-
Install
|
61
|
-
|
62
|
-
::
|
55
|
+
Install SpaCr with pip::
|
63
56
|
|
64
57
|
pip install spacr
|
65
58
|
|
66
|
-
Run
|
67
|
-
|
68
|
-
::
|
59
|
+
Run SpaCr GUI::
|
69
60
|
|
70
|
-
|
61
|
+
spacr
|
@@ -10,19 +10,11 @@ def get_cuda_version():
|
|
10
10
|
except (subprocess.CalledProcessError, FileNotFoundError):
|
11
11
|
return None
|
12
12
|
|
13
|
-
cuda_version = get_cuda_version()
|
14
|
-
|
15
|
-
if cuda_version:
|
16
|
-
dgl_dependency = f'dgl-cu{cuda_version}==0.9.1' # Specify the version of DGL compatible with your setup
|
17
|
-
else:
|
18
|
-
dgl_dependency = 'dgl==0.9.1' # Fallback to CPU version if no CUDA is detected
|
19
|
-
|
20
13
|
# Ensure you have read the README.rst content into a variable, e.g., `long_description`
|
21
14
|
with open("README.rst", "r", encoding="utf-8") as fh:
|
22
15
|
long_description = fh.read()
|
23
16
|
|
24
17
|
dependencies = [
|
25
|
-
dgl_dependency,
|
26
18
|
'torch>=2.2.1,<3.0',
|
27
19
|
'torchvision>=0.17.1,<1.0',
|
28
20
|
'torch-geometric>=2.5.1,<3.0',
|
@@ -52,16 +44,13 @@ dependencies = [
|
|
52
44
|
'ttf_opensans>=2020.10.30',
|
53
45
|
'customtkinter>=5.2.2,<6.0',
|
54
46
|
'biopython>=1.80,<2.0',
|
55
|
-
'lxml>=5.1.0,<6.0',
|
56
|
-
'
|
57
|
-
'superqt>=0.6.7,<0.7',
|
58
|
-
'pyqt6>=6.7.1,<6.8',
|
59
|
-
'pyqtgraph>=0.13.7,<0.14'
|
47
|
+
'lxml>=5.1.0,<6.0',
|
48
|
+
'huggingface-hub>=0.24.0,<0.25'
|
60
49
|
]
|
61
50
|
|
62
51
|
setup(
|
63
52
|
name="spacr",
|
64
|
-
version="0.1.
|
53
|
+
version="0.1.50",
|
65
54
|
author="Einar Birnir Olafsson",
|
66
55
|
author_email="olafsson@med.umich.com",
|
67
56
|
description="Spatial phenotype analysis of crisp screens (SpaCr)",
|
@@ -73,18 +62,17 @@ setup(
|
|
73
62
|
install_requires=dependencies,
|
74
63
|
entry_points={
|
75
64
|
'console_scripts': [
|
76
|
-
'mask=spacr.
|
77
|
-
'measure=spacr.
|
78
|
-
'make_masks=spacr.
|
79
|
-
'
|
80
|
-
'
|
81
|
-
'
|
82
|
-
'
|
83
|
-
'gui=spacr.gui:gui_app',
|
65
|
+
'mask=spacr.app_mask:start_mask_app',
|
66
|
+
'measure=spacr.app_measure:start_measure_app',
|
67
|
+
'make_masks=spacr.app_make_masks:gui_make_masks',
|
68
|
+
'annotate=spacr.app_annotate:gui_annotate',
|
69
|
+
'classify=spacr.app_classify:start_classify_app',
|
70
|
+
'sim=spacr.app_sim:gui_sim',
|
71
|
+
'spacr=spacr.gui:gui_app',
|
84
72
|
],
|
85
73
|
},
|
86
74
|
extras_require={
|
87
|
-
'dev': ['pytest>=3.9'],
|
75
|
+
'dev': ['pytest>=3.9,<3.11'],
|
88
76
|
'headless': ['opencv-python-headless'],
|
89
77
|
'full': ['opencv-python'],
|
90
78
|
},
|
@@ -93,4 +81,32 @@ setup(
|
|
93
81
|
"License :: OSI Approved :: MIT License",
|
94
82
|
"Operating System :: OS Independent",
|
95
83
|
]
|
96
|
-
)
|
84
|
+
)
|
85
|
+
|
86
|
+
cuda_version = get_cuda_version()
|
87
|
+
|
88
|
+
if cuda_version:
|
89
|
+
dgl = f'dgl-cu{cuda_version}==0.9.1'
|
90
|
+
else:
|
91
|
+
dgl = 'dgl==0.9.1' # Fallback to CPU version if no CUDA is detected
|
92
|
+
try:
|
93
|
+
subprocess.run(['pip', 'install', dgl], check=True)
|
94
|
+
except subprocess.CalledProcessError:
|
95
|
+
subprocess.run(['pip', 'install', 'dgl'], check=True)
|
96
|
+
|
97
|
+
deps = ['pyqtgraph>=0.13.7,<0.14',
|
98
|
+
'pyqt6>=6.7.1,<6.8',
|
99
|
+
'pyqt6.sip',
|
100
|
+
'qtpy>=2.4.1,<2.5',
|
101
|
+
'superqt>=0.6.7,<0.7',
|
102
|
+
'pyqtgraph',
|
103
|
+
'pyqt6',
|
104
|
+
'pyqt6.sip',
|
105
|
+
'qtpy',
|
106
|
+
'superqt']
|
107
|
+
|
108
|
+
for dep in deps:
|
109
|
+
try:
|
110
|
+
subprocess.run(['pip', 'install', dep], check=True)
|
111
|
+
except subprocess.CalledProcessError:
|
112
|
+
pass
|
@@ -13,7 +13,7 @@ from IPython.display import display, HTML
|
|
13
13
|
from tkinter import font as tkFont
|
14
14
|
from tkinter import TclError
|
15
15
|
|
16
|
-
from .gui_utils import ScrollableFrame, CustomButton, set_dark_style,
|
16
|
+
from .gui_utils import ScrollableFrame, CustomButton, set_dark_style, create_menu_bar, set_default_font
|
17
17
|
|
18
18
|
class ImageApp:
|
19
19
|
def __init__(self, root, db_path, src, image_type=None, channels=None, grid_rows=None, grid_cols=None, image_size=(200, 200), annotation_column='annotate', normalize=False, percentiles=(1,99), measurement=None, threshold=None):
|
@@ -372,7 +372,6 @@ global_image_refs = []
|
|
372
372
|
def initiate_annotation_app_root(parent_frame):
|
373
373
|
style = ttk.Style(parent_frame)
|
374
374
|
set_dark_style(style)
|
375
|
-
style_text_boxes(style)
|
376
375
|
set_default_font(parent_frame, font_name="Arial", size=8)
|
377
376
|
|
378
377
|
parent_frame.configure(bg='black')
|
@@ -536,4 +535,4 @@ def gui_annotate():
|
|
536
535
|
root.mainloop()
|
537
536
|
|
538
537
|
if __name__ == "__main__":
|
539
|
-
gui_annotate()
|
538
|
+
gui_annotate()
|
@@ -13,7 +13,7 @@ from ttkthemes import ThemedTk
|
|
13
13
|
|
14
14
|
from .logger import log_function_call
|
15
15
|
|
16
|
-
from .gui_utils import ScrollableFrame, CustomButton, set_dark_style,
|
16
|
+
from .gui_utils import ScrollableFrame, CustomButton, set_dark_style, create_menu_bar, set_default_font
|
17
17
|
|
18
18
|
class modify_masks:
|
19
19
|
|
@@ -864,7 +864,6 @@ class modify_masks:
|
|
864
864
|
def initiate_mask_app_root(parent_frame):
|
865
865
|
style = ttk.Style(parent_frame)
|
866
866
|
set_dark_style(style)
|
867
|
-
style_text_boxes(style)
|
868
867
|
set_default_font(parent_frame, font_name="Arial", size=8)
|
869
868
|
|
870
869
|
container = tk.PanedWindow(parent_frame, orient=tk.HORIZONTAL)
|
@@ -13,7 +13,7 @@ from ttkthemes import ThemedTk
|
|
13
13
|
from pyqtgraph import GraphicsLayoutWidget, ViewBox, ImageItem, mkQApp
|
14
14
|
|
15
15
|
from .logger import log_function_call
|
16
|
-
from .gui_utils import ScrollableFrame, CustomButton, set_dark_style,
|
16
|
+
from .gui_utils import ScrollableFrame, CustomButton, set_dark_style, create_dark_mode, create_menu_bar, set_default_font
|
17
17
|
|
18
18
|
class ModifyMasks:
|
19
19
|
def __init__(self, root, folder_path, scale_factor):
|
@@ -635,9 +635,7 @@ def initiate_mask_app_root(width, height):
|
|
635
635
|
root = ThemedTk(theme=theme)
|
636
636
|
style = ttk.Style(root)
|
637
637
|
set_dark_style(style)
|
638
|
-
|
639
|
-
style_text_boxes(style)
|
640
|
-
set_default_font(root, font_name="Arial", size=8)
|
638
|
+
#set_default_font(root, font_name="Arial", size=8)
|
641
639
|
root.geometry(f"{width}x{height}")
|
642
640
|
root.title("Mask App")
|
643
641
|
create_menu_bar(root)
|
@@ -10,6 +10,9 @@ import matplotlib.pyplot as plt
|
|
10
10
|
from PIL import Image
|
11
11
|
|
12
12
|
from .logger import log_function_call
|
13
|
+
from .utils import close_multiprocessing_processes, reset_mp
|
14
|
+
#reset_mp()
|
15
|
+
#close_multiprocessing_processes()
|
13
16
|
|
14
17
|
def evaluate_model_core(model, loader, loader_name, epoch, loss_type):
|
15
18
|
"""
|
@@ -42,7 +45,6 @@ def evaluate_model_core(model, loader, loader_name, epoch, loss_type):
|
|
42
45
|
for batch_idx, (data, target, _) in enumerate(loader, start=1):
|
43
46
|
start_time = time.time()
|
44
47
|
data, target = data.to(device), target.to(device).float()
|
45
|
-
#data, target = data.to(torch.float).to(device), target.to(device).float()
|
46
48
|
output = model(data)
|
47
49
|
loss += F.binary_cross_entropy_with_logits(output, target, reduction='sum').item()
|
48
50
|
loss = calculate_loss(output, target, loss_type=loss_type)
|
@@ -1,20 +1,15 @@
|
|
1
1
|
import tkinter as tk
|
2
2
|
from tkinter import ttk
|
3
|
-
from tkinter import font as tkFont
|
4
3
|
from PIL import Image, ImageTk
|
5
4
|
import os
|
6
5
|
import requests
|
7
|
-
|
8
|
-
|
9
|
-
from .app_mask import initiate_mask_root
|
10
|
-
from .app_measure import initiate_measure_root
|
6
|
+
from multiprocessing import set_start_method
|
7
|
+
from .gui_utils import set_dark_style, create_menu_bar, initiate_root
|
11
8
|
from .app_annotate import initiate_annotation_app_root
|
12
9
|
from .app_make_masks import initiate_mask_app_root
|
13
|
-
from .app_classify import initiate_classify_root
|
14
|
-
from .gui_utils import CustomButton, style_text_boxes, create_menu_bar
|
15
10
|
|
16
11
|
class MainApp(tk.Tk):
|
17
|
-
def __init__(self):
|
12
|
+
def __init__(self, default_app=None):
|
18
13
|
super().__init__()
|
19
14
|
width = self.winfo_screenwidth()
|
20
15
|
height = self.winfo_screenheight()
|
@@ -22,19 +17,31 @@ class MainApp(tk.Tk):
|
|
22
17
|
self.title("SpaCr GUI Collection")
|
23
18
|
self.configure(bg="black")
|
24
19
|
style = ttk.Style()
|
25
|
-
|
20
|
+
set_dark_style(style)
|
26
21
|
|
27
22
|
self.gui_apps = {
|
28
|
-
"Mask": (
|
29
|
-
"Measure": (
|
23
|
+
"Mask": (lambda frame: initiate_root(frame, 'mask'), "Generate cellpose masks for cells, nuclei and pathogen images."),
|
24
|
+
"Measure": (lambda frame: initiate_root(frame, 'measure'), "Measure single object intensity and morphological feature. Crop and save single object image"),
|
30
25
|
"Annotate": (initiate_annotation_app_root, "Annotation single object images on a grid. Annotations are saved to database."),
|
31
26
|
"Make Masks": (initiate_mask_app_root, "Adjust pre-existing Cellpose models to your specific dataset for improved performance"),
|
32
|
-
"Classify": (
|
27
|
+
"Classify": (lambda frame: initiate_root(frame, 'classify'), "Train Torch Convolutional Neural Networks (CNNs) or Transformers to classify single object images.")
|
33
28
|
}
|
34
29
|
|
35
30
|
self.selected_app = tk.StringVar()
|
36
31
|
self.create_widgets()
|
37
32
|
|
33
|
+
|
34
|
+
if default_app == "Mask":
|
35
|
+
self.load_app(default_app, self.gui_apps[default_app][0])
|
36
|
+
elif default_app == "Measure":
|
37
|
+
self.load_app(default_app, self.gui_apps[default_app][1])
|
38
|
+
elif default_app == "Annotate":
|
39
|
+
self.load_app(default_app, self.gui_apps[default_app][2])
|
40
|
+
elif default_app == "Make Masks":
|
41
|
+
self.load_app(default_app, self.gui_apps[default_app][3])
|
42
|
+
elif default_app == "Classify":
|
43
|
+
self.load_app(default_app, self.gui_apps[default_app][4])
|
44
|
+
|
38
45
|
def create_widgets(self):
|
39
46
|
# Create the menu bar
|
40
47
|
create_menu_bar(self)
|
@@ -74,7 +81,8 @@ class MainApp(tk.Tk):
|
|
74
81
|
app_func, app_desc = app_data
|
75
82
|
|
76
83
|
# Create custom button with text
|
77
|
-
button = CustomButton(buttons_frame, text=app_name, command=lambda app_name=app_name: self.load_app(app_name, app_func), font=('Helvetica', 12))
|
84
|
+
#button = CustomButton(buttons_frame, text=app_name, command=lambda app_name=app_name, app_func=app_func: self.load_app(app_name, app_func), font=('Helvetica', 12))
|
85
|
+
button = ttk.Button(buttons_frame, text=app_name, command=lambda app_name=app_name, app_func=app_func: self.load_app(app_name, app_func), style='Custom.TButton')
|
78
86
|
button.grid(row=i, column=0, pady=10, padx=10, sticky="w")
|
79
87
|
|
80
88
|
description_label = tk.Label(buttons_frame, text=app_desc, bg="black", fg="white", wraplength=800, justify="left", font=('Helvetica', 12))
|
@@ -100,7 +108,6 @@ class MainApp(tk.Tk):
|
|
100
108
|
|
101
109
|
try:
|
102
110
|
img_path = os.path.join(os.path.dirname(__file__), 'logo_spacr.png')
|
103
|
-
print(f"Trying to load logo from {img_path}")
|
104
111
|
logo_image = Image.open(img_path)
|
105
112
|
except (FileNotFoundError, Image.UnidentifiedImageError):
|
106
113
|
print(f"File {img_path} not found or is not a valid image. Attempting to download from GitHub.")
|
@@ -117,7 +124,9 @@ class MainApp(tk.Tk):
|
|
117
124
|
print(f"An error occurred while loading the logo: {e}")
|
118
125
|
return False
|
119
126
|
try:
|
120
|
-
|
127
|
+
screen_height = frame.winfo_screenheight()
|
128
|
+
new_height = int(screen_height // 4)
|
129
|
+
logo_image = logo_image.resize((new_height, new_height), Image.Resampling.LANCZOS)
|
121
130
|
logo_photo = ImageTk.PhotoImage(logo_image)
|
122
131
|
logo_label = tk.Label(frame, image=logo_photo, bg="black")
|
123
132
|
logo_label.image = logo_photo # Keep a reference to avoid garbage collection
|
@@ -145,4 +154,5 @@ def gui_app():
|
|
145
154
|
app.mainloop()
|
146
155
|
|
147
156
|
if __name__ == "__main__":
|
148
|
-
|
157
|
+
set_start_method('spawn', force=True)
|
158
|
+
gui_app()
|