spacr 0.2.4__tar.gz → 0.2.5__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.2.4/spacr.egg-info → spacr-0.2.5}/PKG-INFO +5 -1
- {spacr-0.2.4 → spacr-0.2.5}/setup.py +6 -2
- {spacr-0.2.4 → spacr-0.2.5}/spacr/core.py +56 -67
- {spacr-0.2.4 → spacr-0.2.5}/spacr/gui.py +20 -38
- spacr-0.2.5/spacr/gui_core.py +696 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/gui_elements.py +309 -59
- spacr-0.2.5/spacr/gui_utils.py +640 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/io.py +42 -46
- {spacr-0.2.4 → spacr-0.2.5}/spacr/measure.py +198 -151
- {spacr-0.2.4 → spacr-0.2.5}/spacr/plot.py +108 -42
- spacr-0.2.5/spacr/resources/font/open_sans/OFL.txt +93 -0
- spacr-0.2.5/spacr/resources/font/open_sans/OpenSans-Italic-VariableFont_wdth,wght.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/OpenSans-VariableFont_wdth,wght.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/README.txt +100 -0
- spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans-Bold.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans-BoldItalic.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans-ExtraBold.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans-ExtraBoldItalic.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans-Italic.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans-Light.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans-LightItalic.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans-Medium.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans-MediumItalic.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans-Regular.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans-SemiBold.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans-SemiBoldItalic.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_Condensed-Bold.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_Condensed-BoldItalic.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_Condensed-ExtraBold.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_Condensed-ExtraBoldItalic.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_Condensed-Italic.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_Condensed-Light.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_Condensed-LightItalic.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_Condensed-Medium.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_Condensed-MediumItalic.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_Condensed-Regular.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_Condensed-SemiBold.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_Condensed-SemiBoldItalic.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-Bold.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-BoldItalic.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-ExtraBold.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-ExtraBoldItalic.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-Italic.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-Light.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-LightItalic.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-Medium.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-MediumItalic.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-Regular.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-SemiBold.ttf +0 -0
- spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-SemiBoldItalic.ttf +0 -0
- spacr-0.2.5/spacr/resources/icons/logo.pdf +2786 -6
- spacr-0.2.5/spacr/resources/icons/logo_spacr.png +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/settings.py +11 -83
- {spacr-0.2.4 → spacr-0.2.5}/spacr/utils.py +13 -33
- {spacr-0.2.4 → spacr-0.2.5/spacr.egg-info}/PKG-INFO +5 -1
- spacr-0.2.5/spacr.egg-info/SOURCES.txt +120 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr.egg-info/requires.txt +4 -0
- spacr-0.2.4/spacr/gui_core.py +0 -795
- spacr-0.2.4/spacr/gui_utils.py +0 -352
- spacr-0.2.4/spacr.egg-info/SOURCES.txt +0 -78
- {spacr-0.2.4 → spacr-0.2.5}/LICENSE +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/MANIFEST.in +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/README.rst +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/setup.cfg +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/__init__.py +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/__main__.py +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/app_annotate.py +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/app_classify.py +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/app_make_masks.py +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/app_mask.py +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/app_measure.py +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/app_sequencing.py +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/app_umap.py +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/chris.py +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/deep_spacr.py +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/graph_learning.py +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/logger.py +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/abort.png +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/annotate.png +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/cellpose_all.png +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/cellpose_masks.png +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/classify.png +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/default.png +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/download.png +0 -0
- /spacr-0.2.4/spacr/resources/icons/logo_spacr.png → /spacr-0.2.5/spacr/resources/icons/logo_spacr_1.png +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/make_masks.png +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/map_barcodes.png +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/mask.png +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/measure.png +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/ml_analyze.png +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/recruitment.png +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/regression.png +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/run.png +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/sequencing.png +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/settings.png +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/spacr_logo_rotation.gif +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/train_cellpose.png +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/umap.png +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/models/cp/toxo_plaque_cyto_e25000_X1120_Y1120.CP_model +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/models/cp/toxo_plaque_cyto_e25000_X1120_Y1120.CP_model_settings.csv +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/models/cp/toxo_pv_lumen.CP_model +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/sequencing.py +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/sim.py +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/sim_app.py +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/timelapse.py +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr/version.py +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr.egg-info/dependency_links.txt +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr.egg-info/entry_points.txt +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/spacr.egg-info/top_level.txt +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/tests/test_annotate_app.py +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/tests/test_core.py +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/tests/test_gui_classify_app.py +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/tests/test_gui_mask_app.py +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/tests/test_gui_measure_app.py +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/tests/test_gui_sim_app.py +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/tests/test_gui_utils.py +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/tests/test_io.py +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/tests/test_mask_app.py +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/tests/test_measure.py +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/tests/test_plot.py +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/tests/test_sim.py +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/tests/test_timelapse.py +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/tests/test_train.py +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/tests/test_umap.py +0 -0
- {spacr-0.2.4 → spacr-0.2.5}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: spacr
|
3
|
-
Version: 0.2.
|
3
|
+
Version: 0.2.5
|
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
|
@@ -39,6 +39,10 @@ Requires-Dist: ttf_opensans>=2020.10.30
|
|
39
39
|
Requires-Dist: customtkinter<6.0,>=5.2.2
|
40
40
|
Requires-Dist: biopython<2.0,>=1.80
|
41
41
|
Requires-Dist: lxml<6.0,>=5.1.0
|
42
|
+
Requires-Dist: psutil<6.0,>=5.9.8
|
43
|
+
Requires-Dist: gputil<2.0,>=1.4.0
|
44
|
+
Requires-Dist: gpustat<2.0,>=1.1.1
|
45
|
+
Requires-Dist: pyautogui<1.0,>=0.9.54
|
42
46
|
Requires-Dist: huggingface-hub<0.25,>=0.24.0
|
43
47
|
Provides-Extra: dev
|
44
48
|
Requires-Dist: pytest<3.11,>=3.9; extra == "dev"
|
@@ -45,12 +45,16 @@ dependencies = [
|
|
45
45
|
'customtkinter>=5.2.2,<6.0',
|
46
46
|
'biopython>=1.80,<2.0',
|
47
47
|
'lxml>=5.1.0,<6.0',
|
48
|
+
'psutil>=5.9.8, <6.0',
|
49
|
+
'gputil>=1.4.0, <2.0',
|
50
|
+
'gpustat>=1.1.1,<2.0',
|
51
|
+
'pyautogui>=0.9.54,<1.0',
|
48
52
|
'huggingface-hub>=0.24.0,<0.25'
|
49
53
|
]
|
50
54
|
|
51
55
|
setup(
|
52
56
|
name="spacr",
|
53
|
-
version="0.2.
|
57
|
+
version="0.2.5",
|
54
58
|
author="Einar Birnir Olafsson",
|
55
59
|
author_email="olafsson@med.umich.com",
|
56
60
|
description="Spatial phenotype analysis of crisp screens (SpaCr)",
|
@@ -58,7 +62,7 @@ setup(
|
|
58
62
|
url="https://github.com/EinarOlafsson/spacr",
|
59
63
|
packages=find_packages(exclude=["tests.*", "tests"]),
|
60
64
|
include_package_data=True,
|
61
|
-
package_data={'spacr': ['resources/models/cp/*', 'resources/icons/*'],},
|
65
|
+
package_data={'spacr': ['resources/models/cp/*', 'resources/icons/*', 'resources/font/**/*'],},
|
62
66
|
install_requires=dependencies,
|
63
67
|
entry_points={
|
64
68
|
'console_scripts': [
|
@@ -39,6 +39,10 @@ matplotlib.use('Agg')
|
|
39
39
|
|
40
40
|
from .logger import log_function_call
|
41
41
|
|
42
|
+
import warnings
|
43
|
+
warnings.filterwarnings("ignore", message="3D stack used, but stitch_threshold=0 and do_3D=False, so masks are made per plane only")
|
44
|
+
|
45
|
+
|
42
46
|
def analyze_plaques(folder):
|
43
47
|
summary_data = []
|
44
48
|
details_data = []
|
@@ -80,7 +84,6 @@ def analyze_plaques(folder):
|
|
80
84
|
|
81
85
|
print(f"Analysis completed and saved to database '{db_name}'.")
|
82
86
|
|
83
|
-
|
84
87
|
def train_cellpose(settings):
|
85
88
|
|
86
89
|
from .io import _load_normalized_images_and_labels, _load_images_and_labels
|
@@ -1032,10 +1035,6 @@ def apply_model_to_tar(tar_path, model_path, file_type='cell_png', image_size=22
|
|
1032
1035
|
files_to_process = len(data_loader)
|
1033
1036
|
print_progress(files_processed, files_to_process, n_jobs=n_jobs, time_ls=time_ls, batch_size=batch_size, operation_type="Tar dataset")
|
1034
1037
|
|
1035
|
-
|
1036
|
-
|
1037
|
-
|
1038
|
-
|
1039
1038
|
data = {'path':filenames_list, 'pred':prediction_pos_probs}
|
1040
1039
|
df = pd.DataFrame(data, index=None)
|
1041
1040
|
df = process_vision_results(df, threshold)
|
@@ -1695,9 +1694,9 @@ def analyze_recruitment(src, metadata_settings={}, advanced_settings={}):
|
|
1695
1694
|
def preprocess_generate_masks(src, settings={}):
|
1696
1695
|
|
1697
1696
|
from .io import preprocess_img_data, _load_and_concatenate_arrays
|
1698
|
-
from .plot import
|
1699
|
-
from .utils import _pivot_counts_table, check_mask_folder, adjust_cell_masks
|
1700
|
-
from .settings import set_default_settings_preprocess_generate_masks
|
1697
|
+
from .plot import plot_image_mask_overlay, plot_arrays
|
1698
|
+
from .utils import _pivot_counts_table, check_mask_folder, adjust_cell_masks, print_progress
|
1699
|
+
from .settings import set_default_settings_preprocess_generate_masks
|
1701
1700
|
|
1702
1701
|
settings = set_default_settings_preprocess_generate_masks(src, settings)
|
1703
1702
|
settings_df = pd.DataFrame(list(settings.items()), columns=['Key', 'Value'])
|
@@ -1730,20 +1729,43 @@ def preprocess_generate_masks(src, settings={}):
|
|
1730
1729
|
|
1731
1730
|
if settings['preprocess']:
|
1732
1731
|
settings, src = preprocess_img_data(settings)
|
1733
|
-
|
1732
|
+
|
1733
|
+
files_to_process = 3
|
1734
1734
|
if settings['masks']:
|
1735
1735
|
mask_src = os.path.join(src, 'norm_channel_stack')
|
1736
1736
|
if settings['cell_channel'] != None:
|
1737
|
+
start = time.time()
|
1737
1738
|
if check_mask_folder(src, 'cell_mask_stack'):
|
1738
1739
|
generate_cellpose_masks(mask_src, settings, 'cell')
|
1740
|
+
stop = time.time()
|
1741
|
+
duration = (stop - start)
|
1742
|
+
time_ls.append(duration)
|
1743
|
+
files_processed += 1
|
1744
|
+
print_progress(files_processed, files_to_process, n_jobs=1, time_ls=time_ls, batch_size=None, operation_type=f'cell_mask_gen')
|
1739
1745
|
|
1740
1746
|
if settings['nucleus_channel'] != None:
|
1747
|
+
start = time.time()
|
1741
1748
|
if check_mask_folder(src, 'nucleus_mask_stack'):
|
1742
1749
|
generate_cellpose_masks(mask_src, settings, 'nucleus')
|
1750
|
+
stop = time.time()
|
1751
|
+
duration = (stop - start)
|
1752
|
+
time_ls.append(duration)
|
1753
|
+
files_processed += 1
|
1754
|
+
print_progress(files_processed, files_to_process, n_jobs=1, time_ls=time_ls, batch_size=None, operation_type=f'nucleus_mask_gen')
|
1743
1755
|
|
1744
1756
|
if settings['pathogen_channel'] != None:
|
1757
|
+
start = time.time()
|
1745
1758
|
if check_mask_folder(src, 'pathogen_mask_stack'):
|
1759
|
+
stop = time.time()
|
1760
|
+
duration = (stop - start)
|
1761
|
+
time_ls.append(duration)
|
1762
|
+
files_processed += 1
|
1746
1763
|
generate_cellpose_masks(mask_src, settings, 'pathogen')
|
1764
|
+
print_progress(files_processed, files_to_process, n_jobs=1, time_ls=time_ls, batch_size=None, operation_type=f'pathogen_mask_gen')
|
1765
|
+
|
1766
|
+
#if settings['organelle'] != None:
|
1767
|
+
# if check_mask_folder(src, 'organelle_mask_stack'):
|
1768
|
+
# generate_cellpose_masks(mask_src, settings, 'organelle')
|
1747
1769
|
|
1748
1770
|
if settings['adjust_cells']:
|
1749
1771
|
if settings['pathogen_channel'] != None and settings['cell_channel'] != None and settings['nucleus_channel'] != None:
|
@@ -1752,12 +1774,8 @@ def preprocess_generate_masks(src, settings={}):
|
|
1752
1774
|
cell_folder = os.path.join(mask_src, 'cell_mask_stack')
|
1753
1775
|
nuclei_folder = os.path.join(mask_src, 'nucleus_mask_stack')
|
1754
1776
|
parasite_folder = os.path.join(mask_src, 'pathogen_mask_stack')
|
1755
|
-
#
|
1777
|
+
#organelle_folder = os.path.join(mask_src, 'organelle_mask_stack')
|
1756
1778
|
|
1757
|
-
#process_masks(cell_folder, image_folder, settings['cell_channel'], settings['batch_size'], n_clusters=2, plot=settings['plot'])
|
1758
|
-
#process_masks(nuclei_folder, image_folder, settings['nucleus_channel'], settings['batch_size'], n_clusters=2, plot=settings['plot'])
|
1759
|
-
#process_masks(parasite_folder, image_folder, settings['pathogen_channel'], settings['batch_size'], n_clusters=2, plot=settings['plot'])
|
1760
|
-
|
1761
1779
|
adjust_cell_masks(parasite_folder, cell_folder, nuclei_folder, overlap_threshold=5, perimeter_threshold=30)
|
1762
1780
|
stop = time.time()
|
1763
1781
|
adjust_time = (stop-start)/60
|
@@ -1771,38 +1789,28 @@ def preprocess_generate_masks(src, settings={}):
|
|
1771
1789
|
|
1772
1790
|
if settings['plot']:
|
1773
1791
|
if not settings['timelapse']:
|
1774
|
-
plot_dims = len(settings['channels'])
|
1775
|
-
overlay_channels = [2,1,0]
|
1776
|
-
cell_mask_dim = nucleus_mask_dim = pathogen_mask_dim = None
|
1777
|
-
plot_counter = plot_dims
|
1778
|
-
|
1779
|
-
if settings['cell_channel'] is not None:
|
1780
|
-
cell_mask_dim = plot_counter
|
1781
|
-
plot_counter += 1
|
1782
|
-
|
1783
|
-
if settings['nucleus_channel'] is not None:
|
1784
|
-
nucleus_mask_dim = plot_counter
|
1785
|
-
plot_counter += 1
|
1786
|
-
|
1787
|
-
if settings['pathogen_channel'] is not None:
|
1788
|
-
pathogen_mask_dim = plot_counter
|
1789
|
-
|
1790
|
-
overlay_channels = [settings['nucleus_channel'], settings['pathogen_channel'], settings['cell_channel']]
|
1791
|
-
overlay_channels = [element for element in overlay_channels if element is not None]
|
1792
|
-
|
1793
|
-
plot_settings = set_default_plot_merge_settings()
|
1794
|
-
plot_settings['channel_dims'] = settings['channels']
|
1795
|
-
plot_settings['cell_mask_dim'] = cell_mask_dim
|
1796
|
-
plot_settings['nucleus_mask_dim'] = nucleus_mask_dim
|
1797
|
-
plot_settings['pathogen_mask_dim'] = pathogen_mask_dim
|
1798
|
-
plot_settings['overlay_chans'] = overlay_channels
|
1799
|
-
plot_settings['nr'] = settings['examples_to_plot']
|
1800
1792
|
|
1801
1793
|
if settings['test_mode'] == True:
|
1802
|
-
|
1794
|
+
settings['examples_to_plot'] = len(os.path.join(src,'merged'))
|
1803
1795
|
|
1804
1796
|
try:
|
1805
|
-
|
1797
|
+
merged_src = os.path.join(src,'merged')
|
1798
|
+
files = os.listdir(merged_src)
|
1799
|
+
random.shuffle(files)
|
1800
|
+
time_ls = []
|
1801
|
+
|
1802
|
+
for i, file in enumerate(files):
|
1803
|
+
start = time.time()
|
1804
|
+
if i+1 <= settings['examples_to_plot']:
|
1805
|
+
file_path = os.path.join(merged_src, file)
|
1806
|
+
plot_image_mask_overlay(file_path, settings['channels'], settings['cell_channel'], settings['nucleus_channel'], settings['pathogen_channel'], figuresize=10, normalize=True, thickness=3, save_pdf=True)
|
1807
|
+
stop = time.time()
|
1808
|
+
duration = stop-start
|
1809
|
+
time_ls.append(duration)
|
1810
|
+
files_processed = i+1
|
1811
|
+
files_to_process = settings['examples_to_plot']
|
1812
|
+
print_progress(files_processed, files_to_process, n_jobs=1, time_ls=time_ls, batch_size=None, operation_type="Plot mask outlines")
|
1813
|
+
print("Successfully completed run")
|
1806
1814
|
except Exception as e:
|
1807
1815
|
print(f'Failed to plot image mask overly. Error: {e}')
|
1808
1816
|
else:
|
@@ -2010,7 +2018,7 @@ def generate_cellpose_masks(src, settings, object_type):
|
|
2010
2018
|
|
2011
2019
|
if object_type == 'pathogen' and not settings['pathogen_model'] is None:
|
2012
2020
|
model_name = settings['pathogen_model']
|
2013
|
-
|
2021
|
+
|
2014
2022
|
model = _choose_model(model_name, device, object_type=object_type, restore_type=None, object_settings=object_settings)
|
2015
2023
|
|
2016
2024
|
chans = [2, 1] if model_name == 'cyto2' else [0,0] if model_name == 'nucleus' else [2,0] if model_name == 'cyto' else [2, 0] if model_name == 'cyto3' else [2, 0]
|
@@ -2022,16 +2030,18 @@ def generate_cellpose_masks(src, settings, object_type):
|
|
2022
2030
|
|
2023
2031
|
average_sizes = []
|
2024
2032
|
time_ls = []
|
2033
|
+
|
2025
2034
|
for file_index, path in enumerate(paths):
|
2026
2035
|
name = os.path.basename(path)
|
2027
2036
|
name, ext = os.path.splitext(name)
|
2028
2037
|
output_folder = os.path.join(os.path.dirname(path), object_type+'_mask_stack')
|
2029
2038
|
os.makedirs(output_folder, exist_ok=True)
|
2030
2039
|
overall_average_size = 0
|
2040
|
+
|
2031
2041
|
with np.load(path) as data:
|
2032
2042
|
stack = data['data']
|
2033
2043
|
filenames = data['filenames']
|
2034
|
-
|
2044
|
+
|
2035
2045
|
for i, filename in enumerate(filenames):
|
2036
2046
|
output_path = os.path.join(output_folder, filename)
|
2037
2047
|
|
@@ -2057,11 +2067,8 @@ def generate_cellpose_masks(src, settings, object_type):
|
|
2057
2067
|
batch_size = len(stack)
|
2058
2068
|
print(f'Cut batch at indecies: {timelapse_frame_limits}, New batch_size: {batch_size} ')
|
2059
2069
|
|
2060
|
-
files_processed = 0
|
2061
2070
|
for i in range(0, stack.shape[0], batch_size):
|
2062
2071
|
mask_stack = []
|
2063
|
-
start = time.time()
|
2064
|
-
|
2065
2072
|
if stack.shape[3] == 1:
|
2066
2073
|
batch = stack[i: i+batch_size, :, :, [0,0]].astype(stack.dtype)
|
2067
2074
|
else:
|
@@ -2072,7 +2079,6 @@ def generate_cellpose_masks(src, settings, object_type):
|
|
2072
2079
|
if not settings['plot']:
|
2073
2080
|
batch, batch_filenames = _check_masks(batch, batch_filenames, output_folder)
|
2074
2081
|
if batch.size == 0:
|
2075
|
-
print(f'Processing {file_index}/{len(paths)}: Images/npz {batch.shape[0]}')
|
2076
2082
|
continue
|
2077
2083
|
|
2078
2084
|
batch = prepare_batch_for_cellpose(batch)
|
@@ -2083,16 +2089,6 @@ def generate_cellpose_masks(src, settings, object_type):
|
|
2083
2089
|
save_path = os.path.join(movie_path, f'timelapse_{object_type}_{name}.mp4')
|
2084
2090
|
_npz_to_movie(batch, batch_filenames, save_path, fps=2)
|
2085
2091
|
|
2086
|
-
if settings['verbose']:
|
2087
|
-
print(f'Processing {file_index}/{len(paths)}: Images/npz {batch.shape[0]}')
|
2088
|
-
|
2089
|
-
#cellpose_normalize_dict = {'lowhigh':[0.0,1.0], #pass in normalization values for 0.0 and 1.0 as list [low, high] if None all other keys ignored
|
2090
|
-
# 'sharpen':object_settings['diameter']/4, #recommended to be 1/4-1/8 diameter of cells in pixels
|
2091
|
-
# 'normalize':True, #(if False, all following parameters ignored)
|
2092
|
-
# 'percentile':[2,98], #[perc_low, perc_high]
|
2093
|
-
# 'tile_norm':224, #normalize by tile set to e.g. 100 for normailize window to be 100 px
|
2094
|
-
# 'norm3D':True} #compute normalization across entire z-stack rather than plane-by-plane in stitching mode.
|
2095
|
-
|
2096
2092
|
output = model.eval(x=batch,
|
2097
2093
|
batch_size=cellpose_batch_size,
|
2098
2094
|
normalize=False,
|
@@ -2202,16 +2198,8 @@ def generate_cellpose_masks(src, settings, object_type):
|
|
2202
2198
|
|
2203
2199
|
average_sizes.append(average_obj_size)
|
2204
2200
|
overall_average_size = np.mean(average_sizes) if len(average_sizes) > 0 else 0
|
2201
|
+
print(f'object_size:{object_type}: {overall_average_size:.3f} px2')
|
2205
2202
|
|
2206
|
-
stop = time.time()
|
2207
|
-
duration = (stop - start)
|
2208
|
-
time_ls.append(duration)
|
2209
|
-
files_processed += len(batch_filenames)
|
2210
|
-
#files_processed = (file_index+1)*(batch_size+1)
|
2211
|
-
files_to_process = (len(paths))*(batch_size)
|
2212
|
-
print_progress(files_processed, files_to_process, n_jobs=1, time_ls=time_ls, batch_size=batch_size, operation_type=f'{object_type}_mask_gen')
|
2213
|
-
print(f'object_size:{object_type}): {overall_average_size:.3f} px2')
|
2214
|
-
|
2215
2203
|
if not timelapse:
|
2216
2204
|
if settings['plot']:
|
2217
2205
|
plot_masks(batch, mask_stack, flows, figuresize=figuresize, cmap='inferno', nr=batch_size)
|
@@ -2222,6 +2210,7 @@ def generate_cellpose_masks(src, settings, object_type):
|
|
2222
2210
|
np.save(output_filename, mask)
|
2223
2211
|
mask_stack = []
|
2224
2212
|
batch_filenames = []
|
2213
|
+
|
2225
2214
|
gc.collect()
|
2226
2215
|
torch.cuda.empty_cache()
|
2227
2216
|
return
|
@@ -15,30 +15,29 @@ class MainApp(tk.Tk):
|
|
15
15
|
self.title("SpaCr GUI Collection")
|
16
16
|
self.configure(bg='#333333') # Set window background to dark gray
|
17
17
|
|
18
|
-
# Initialize style and apply dark style to the main window
|
19
18
|
style = ttk.Style()
|
20
19
|
self.color_settings = set_dark_style(style, parent_frame=self)
|
21
|
-
self.main_buttons = {}
|
22
|
-
self.additional_buttons = {}
|
20
|
+
self.main_buttons = {}
|
21
|
+
self.additional_buttons = {}
|
23
22
|
|
24
23
|
self.main_gui_apps = {
|
25
|
-
"Mask": (lambda frame: initiate_root(
|
26
|
-
"Measure": (lambda frame: initiate_root(
|
27
|
-
"Annotate": (lambda frame: initiate_root(
|
28
|
-
"Make Masks": (lambda frame: initiate_root(
|
29
|
-
"Classify": (lambda frame: initiate_root(
|
24
|
+
"Mask": (lambda frame: initiate_root(self, 'mask'), "Generate cellpose masks for cells, nuclei and pathogen images."),
|
25
|
+
"Measure": (lambda frame: initiate_root(self, 'measure'), "Measure single object intensity and morphological feature. Crop and save single object image"),
|
26
|
+
"Annotate": (lambda frame: initiate_root(self, 'annotate'), "Annotation single object images on a grid. Annotations are saved to database."),
|
27
|
+
"Make Masks": (lambda frame: initiate_root(self, 'make_masks'), "Adjust pre-existing Cellpose models to your specific dataset for improved performance"),
|
28
|
+
"Classify": (lambda frame: initiate_root(self, 'classify'), "Train Torch Convolutional Neural Networks (CNNs) or Transformers to classify single object images."),
|
30
29
|
}
|
31
30
|
|
32
31
|
self.additional_gui_apps = {
|
33
|
-
"Sequencing": (lambda frame: initiate_root(
|
34
|
-
"Umap": (lambda frame: initiate_root(
|
35
|
-
"Train Cellpose": (lambda frame: initiate_root(
|
36
|
-
"ML Analyze": (lambda frame: initiate_root(
|
37
|
-
"Cellpose Masks": (lambda frame: initiate_root(
|
38
|
-
"Cellpose All": (lambda frame: initiate_root(
|
39
|
-
"Map Barcodes": (lambda frame: initiate_root(
|
40
|
-
"Regression": (lambda frame: initiate_root(
|
41
|
-
"Recruitment": (lambda frame: initiate_root(
|
32
|
+
"Sequencing": (lambda frame: initiate_root(self, 'sequencing'), "Analyze sequencing data."),
|
33
|
+
"Umap": (lambda frame: initiate_root(self, 'umap'), "Generate UMAP embeddings with datapoints represented as images."),
|
34
|
+
"Train Cellpose": (lambda frame: initiate_root(self, 'train_cellpose'), "Train custom Cellpose models."),
|
35
|
+
"ML Analyze": (lambda frame: initiate_root(self, 'ml_analyze'), "Machine learning analysis of data."),
|
36
|
+
"Cellpose Masks": (lambda frame: initiate_root(self, 'cellpose_masks'), "Generate Cellpose masks."),
|
37
|
+
"Cellpose All": (lambda frame: initiate_root(self, 'cellpose_all'), "Run Cellpose on all images."),
|
38
|
+
"Map Barcodes": (lambda frame: initiate_root(self, 'map_barcodes'), "Map barcodes to data."),
|
39
|
+
"Regression": (lambda frame: initiate_root(self, 'regression'), "Perform regression analysis."),
|
40
|
+
"Recruitment": (lambda frame: initiate_root(self, 'recruitment'), "Analyze recruitment data.")
|
42
41
|
}
|
43
42
|
|
44
43
|
self.selected_app = tk.StringVar()
|
@@ -50,32 +49,25 @@ class MainApp(tk.Tk):
|
|
50
49
|
self.load_app(default_app, self.additional_gui_apps[default_app][0])
|
51
50
|
|
52
51
|
def create_widgets(self):
|
53
|
-
# Create the menu bar
|
54
52
|
create_menu_bar(self)
|
55
53
|
|
56
|
-
# Create a canvas to hold the selected app and other elements
|
57
54
|
self.canvas = tk.Canvas(self, highlightthickness=0)
|
58
55
|
self.canvas.grid(row=0, column=0, sticky="nsew")
|
59
56
|
self.grid_rowconfigure(0, weight=1)
|
60
57
|
self.grid_columnconfigure(0, weight=1)
|
61
58
|
|
62
|
-
# Create a frame inside the canvas to hold the main content
|
63
59
|
self.content_frame = tk.Frame(self.canvas)
|
64
60
|
self.content_frame.grid(row=0, column=0, sticky="nsew")
|
65
61
|
|
66
|
-
# Center the content frame within the canvas
|
67
62
|
self.canvas.create_window((self.winfo_screenwidth() // 2, self.winfo_screenheight() // 2), window=self.content_frame, anchor="center")
|
68
63
|
|
69
|
-
# Apply dark style to canvas and content_frame
|
70
64
|
set_dark_style(ttk.Style(), containers=[self.canvas, self.content_frame])
|
71
65
|
|
72
|
-
# Create startup screen with buttons for each main GUI app and drop-down for additional apps
|
73
66
|
self.create_startup_screen()
|
74
67
|
|
75
68
|
def create_startup_screen(self):
|
76
69
|
self.clear_frame(self.content_frame)
|
77
70
|
|
78
|
-
# Create frames for the grids
|
79
71
|
main_buttons_frame = tk.Frame(self.content_frame)
|
80
72
|
main_buttons_frame.pack(pady=10)
|
81
73
|
set_dark_style(ttk.Style(), containers=[main_buttons_frame])
|
@@ -84,41 +76,33 @@ class MainApp(tk.Tk):
|
|
84
76
|
additional_buttons_frame.pack(pady=10)
|
85
77
|
set_dark_style(ttk.Style(), containers=[additional_buttons_frame])
|
86
78
|
|
87
|
-
# Create a frame for the description below the icon grids
|
88
79
|
description_frame = tk.Frame(self.content_frame, height=70)
|
89
80
|
description_frame.pack(fill=tk.X, pady=10)
|
90
|
-
description_frame.pack_propagate(False)
|
81
|
+
description_frame.pack_propagate(False)
|
91
82
|
set_dark_style(ttk.Style(), containers=[description_frame])
|
92
83
|
|
93
|
-
# Use a Label widget to display descriptions
|
94
84
|
self.description_label = tk.Label(description_frame, text="", wraplength=800, justify="center", font=('Helvetica', 12), fg=self.color_settings['fg_color'], bg=self.color_settings['bg_color'])
|
95
85
|
self.description_label.pack(fill=tk.BOTH, pady=10)
|
96
86
|
|
97
|
-
# Load the logo image and place it in the main apps row
|
98
87
|
logo_button = spacrButton(main_buttons_frame, text="SpaCr", command=lambda: self.load_app("logo_spacr", initiate_root), icon_name="logo_spacr", size=100, show_text=False)
|
99
88
|
logo_button.grid(row=0, column=0, padx=5, pady=5)
|
100
89
|
self.main_buttons[logo_button] = "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.."
|
101
90
|
|
102
|
-
# Create icon buttons for the main apps
|
103
91
|
for i, (app_name, app_data) in enumerate(self.main_gui_apps.items()):
|
104
92
|
app_func, app_desc = app_data
|
105
93
|
button = spacrButton(main_buttons_frame, text=app_name, command=lambda app_name=app_name, app_func=app_func: self.load_app(app_name, app_func), icon_name=app_name.lower(), size=100, show_text=False)
|
106
94
|
button.grid(row=0, column=i + 1, padx=5, pady=5)
|
107
95
|
self.main_buttons[button] = app_desc
|
108
96
|
|
109
|
-
# Create icon buttons for the additional apps
|
110
97
|
for i, (app_name, app_data) in enumerate(self.additional_gui_apps.items()):
|
111
98
|
app_func, app_desc = app_data
|
112
99
|
button = spacrButton(additional_buttons_frame, text=app_name, command=lambda app_name=app_name, app_func=app_func: self.load_app(app_name, app_func), icon_name=app_name.lower(), size=75, show_text=False)
|
113
100
|
button.grid(row=0, column=i, padx=5, pady=5)
|
114
101
|
self.additional_buttons[button] = app_desc
|
115
102
|
|
116
|
-
# Update description initially
|
117
103
|
self.update_description()
|
118
|
-
#
|
119
104
|
|
120
105
|
def update_description(self):
|
121
|
-
# Check all buttons and update description if any has the active color
|
122
106
|
for button, desc in {**self.main_buttons, **self.additional_buttons}.items():
|
123
107
|
if button.canvas.itemcget(button.button_bg, "fill") == self.color_settings['active_color']:
|
124
108
|
self.show_description(desc)
|
@@ -128,18 +112,16 @@ class MainApp(tk.Tk):
|
|
128
112
|
def show_description(self, description):
|
129
113
|
if self.description_label.winfo_exists():
|
130
114
|
self.description_label.config(text=description)
|
131
|
-
self.description_label.update_idletasks()
|
115
|
+
self.description_label.update_idletasks()
|
132
116
|
|
133
117
|
def clear_description(self):
|
134
118
|
if self.description_label.winfo_exists():
|
135
119
|
self.description_label.config(text="")
|
136
|
-
self.description_label.update_idletasks()
|
120
|
+
self.description_label.update_idletasks()
|
137
121
|
|
138
122
|
def load_app(self, app_name, app_func):
|
139
|
-
# Clear the current content frame
|
140
123
|
self.clear_frame(self.canvas)
|
141
124
|
|
142
|
-
# Initialize the selected app
|
143
125
|
app_frame = tk.Frame(self.canvas)
|
144
126
|
app_frame.pack(fill=tk.BOTH, expand=True)
|
145
127
|
set_dark_style(ttk.Style(), containers=[app_frame])
|
@@ -155,4 +137,4 @@ def gui_app():
|
|
155
137
|
|
156
138
|
if __name__ == "__main__":
|
157
139
|
set_start_method('spawn', force=True)
|
158
|
-
gui_app()
|
140
|
+
gui_app()
|