spacr 0.2.32__tar.gz → 0.2.45__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.32/spacr.egg-info → spacr-0.2.45}/PKG-INFO +4 -1
- {spacr-0.2.32 → spacr-0.2.45}/setup.py +4 -1
- {spacr-0.2.32 → spacr-0.2.45}/spacr/core.py +46 -59
- {spacr-0.2.32 → spacr-0.2.45}/spacr/gui.py +20 -38
- spacr-0.2.45/spacr/gui_core.py +710 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/gui_elements.py +198 -56
- spacr-0.2.45/spacr/gui_utils.py +610 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/io.py +29 -38
- {spacr-0.2.32 → spacr-0.2.45}/spacr/measure.py +6 -9
- {spacr-0.2.32 → spacr-0.2.45}/spacr/plot.py +106 -0
- spacr-0.2.45/spacr/resources/icons/logo.pdf +2786 -6
- spacr-0.2.45/spacr/resources/icons/logo_spacr.png +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/settings.py +1 -1
- {spacr-0.2.32 → spacr-0.2.45}/spacr/utils.py +4 -24
- {spacr-0.2.32 → spacr-0.2.45/spacr.egg-info}/PKG-INFO +4 -1
- {spacr-0.2.32 → spacr-0.2.45}/spacr.egg-info/SOURCES.txt +2 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr.egg-info/requires.txt +3 -0
- spacr-0.2.32/spacr/gui_core.py +0 -795
- spacr-0.2.32/spacr/gui_utils.py +0 -352
- {spacr-0.2.32 → spacr-0.2.45}/LICENSE +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/MANIFEST.in +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/README.rst +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/setup.cfg +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/__init__.py +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/__main__.py +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/app_annotate.py +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/app_classify.py +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/app_make_masks.py +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/app_mask.py +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/app_measure.py +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/app_sequencing.py +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/app_umap.py +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/chris.py +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/deep_spacr.py +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/graph_learning.py +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/logger.py +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/resources/icons/abort.png +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/resources/icons/annotate.png +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/resources/icons/cellpose_all.png +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/resources/icons/cellpose_masks.png +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/resources/icons/classify.png +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/resources/icons/default.png +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/resources/icons/download.png +0 -0
- /spacr-0.2.32/spacr/resources/icons/logo_spacr.png → /spacr-0.2.45/spacr/resources/icons/logo_spacr_1.png +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/resources/icons/make_masks.png +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/resources/icons/map_barcodes.png +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/resources/icons/mask.png +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/resources/icons/measure.png +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/resources/icons/ml_analyze.png +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/resources/icons/recruitment.png +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/resources/icons/regression.png +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/resources/icons/run.png +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/resources/icons/sequencing.png +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/resources/icons/settings.png +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/resources/icons/spacr_logo_rotation.gif +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/resources/icons/train_cellpose.png +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/resources/icons/umap.png +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/resources/models/cp/toxo_plaque_cyto_e25000_X1120_Y1120.CP_model +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/resources/models/cp/toxo_plaque_cyto_e25000_X1120_Y1120.CP_model_settings.csv +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/resources/models/cp/toxo_pv_lumen.CP_model +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/sequencing.py +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/sim.py +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/sim_app.py +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/timelapse.py +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr/version.py +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr.egg-info/dependency_links.txt +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr.egg-info/entry_points.txt +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/spacr.egg-info/top_level.txt +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/tests/test_annotate_app.py +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/tests/test_core.py +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/tests/test_gui_classify_app.py +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/tests/test_gui_mask_app.py +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/tests/test_gui_measure_app.py +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/tests/test_gui_sim_app.py +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/tests/test_gui_utils.py +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/tests/test_io.py +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/tests/test_mask_app.py +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/tests/test_measure.py +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/tests/test_plot.py +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/tests/test_sim.py +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/tests/test_timelapse.py +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/tests/test_train.py +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/tests/test_umap.py +0 -0
- {spacr-0.2.32 → spacr-0.2.45}/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.45
|
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,9 @@ 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
|
42
45
|
Requires-Dist: huggingface-hub<0.25,>=0.24.0
|
43
46
|
Provides-Extra: dev
|
44
47
|
Requires-Dist: pytest<3.11,>=3.9; extra == "dev"
|
@@ -45,12 +45,15 @@ 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',
|
48
51
|
'huggingface-hub>=0.24.0,<0.25'
|
49
52
|
]
|
50
53
|
|
51
54
|
setup(
|
52
55
|
name="spacr",
|
53
|
-
version="0.2.
|
56
|
+
version="0.2.45",
|
54
57
|
author="Einar Birnir Olafsson",
|
55
58
|
author_email="olafsson@med.umich.com",
|
56
59
|
description="Spatial phenotype analysis of crisp screens (SpaCr)",
|
@@ -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'])
|
@@ -1745,6 +1744,10 @@ def preprocess_generate_masks(src, settings={}):
|
|
1745
1744
|
if check_mask_folder(src, 'pathogen_mask_stack'):
|
1746
1745
|
generate_cellpose_masks(mask_src, settings, 'pathogen')
|
1747
1746
|
|
1747
|
+
#if settings['organelle'] != None:
|
1748
|
+
# if check_mask_folder(src, 'organelle_mask_stack'):
|
1749
|
+
# generate_cellpose_masks(mask_src, settings, 'organelle')
|
1750
|
+
|
1748
1751
|
if settings['adjust_cells']:
|
1749
1752
|
if settings['pathogen_channel'] != None and settings['cell_channel'] != None and settings['nucleus_channel'] != None:
|
1750
1753
|
|
@@ -1752,12 +1755,8 @@ def preprocess_generate_masks(src, settings={}):
|
|
1752
1755
|
cell_folder = os.path.join(mask_src, 'cell_mask_stack')
|
1753
1756
|
nuclei_folder = os.path.join(mask_src, 'nucleus_mask_stack')
|
1754
1757
|
parasite_folder = os.path.join(mask_src, 'pathogen_mask_stack')
|
1755
|
-
#
|
1758
|
+
#organelle_folder = os.path.join(mask_src, 'organelle_mask_stack')
|
1756
1759
|
|
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
1760
|
adjust_cell_masks(parasite_folder, cell_folder, nuclei_folder, overlap_threshold=5, perimeter_threshold=30)
|
1762
1761
|
stop = time.time()
|
1763
1762
|
adjust_time = (stop-start)/60
|
@@ -1771,38 +1770,28 @@ def preprocess_generate_masks(src, settings={}):
|
|
1771
1770
|
|
1772
1771
|
if settings['plot']:
|
1773
1772
|
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
1773
|
|
1801
1774
|
if settings['test_mode'] == True:
|
1802
|
-
|
1775
|
+
settings['examples_to_plot'] = len(os.path.join(src,'merged'))
|
1803
1776
|
|
1804
1777
|
try:
|
1805
|
-
|
1778
|
+
merged_src = os.path.join(src,'merged')
|
1779
|
+
files = os.listdir(merged_src)
|
1780
|
+
random.shuffle(files)
|
1781
|
+
time_ls = []
|
1782
|
+
|
1783
|
+
for i, file in enumerate(files):
|
1784
|
+
start = time.time()
|
1785
|
+
if i <= settings['examples_to_plot']:
|
1786
|
+
file_path = os.path.join(merged_src, file)
|
1787
|
+
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)
|
1788
|
+
stop = time.time()
|
1789
|
+
duration = stop-start
|
1790
|
+
time_ls.append(duration)
|
1791
|
+
files_processed = i+1
|
1792
|
+
files_to_process = settings['examples_to_plot']
|
1793
|
+
print_progress(files_processed, files_to_process, n_jobs=1, time_ls=time_ls, batch_size=None, operation_type="Plot mask outlines")
|
1794
|
+
print("Successfully completed run")
|
1806
1795
|
except Exception as e:
|
1807
1796
|
print(f'Failed to plot image mask overly. Error: {e}')
|
1808
1797
|
else:
|
@@ -2010,7 +1999,7 @@ def generate_cellpose_masks(src, settings, object_type):
|
|
2010
1999
|
|
2011
2000
|
if object_type == 'pathogen' and not settings['pathogen_model'] is None:
|
2012
2001
|
model_name = settings['pathogen_model']
|
2013
|
-
|
2002
|
+
|
2014
2003
|
model = _choose_model(model_name, device, object_type=object_type, restore_type=None, object_settings=object_settings)
|
2015
2004
|
|
2016
2005
|
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 +2011,20 @@ def generate_cellpose_masks(src, settings, object_type):
|
|
2022
2011
|
|
2023
2012
|
average_sizes = []
|
2024
2013
|
time_ls = []
|
2014
|
+
|
2015
|
+
files_to_process = len(paths)
|
2025
2016
|
for file_index, path in enumerate(paths):
|
2017
|
+
start = time.time()
|
2026
2018
|
name = os.path.basename(path)
|
2027
2019
|
name, ext = os.path.splitext(name)
|
2028
2020
|
output_folder = os.path.join(os.path.dirname(path), object_type+'_mask_stack')
|
2029
2021
|
os.makedirs(output_folder, exist_ok=True)
|
2030
2022
|
overall_average_size = 0
|
2023
|
+
|
2031
2024
|
with np.load(path) as data:
|
2032
2025
|
stack = data['data']
|
2033
2026
|
filenames = data['filenames']
|
2034
|
-
|
2027
|
+
|
2035
2028
|
for i, filename in enumerate(filenames):
|
2036
2029
|
output_path = os.path.join(output_folder, filename)
|
2037
2030
|
|
@@ -2057,11 +2050,8 @@ def generate_cellpose_masks(src, settings, object_type):
|
|
2057
2050
|
batch_size = len(stack)
|
2058
2051
|
print(f'Cut batch at indecies: {timelapse_frame_limits}, New batch_size: {batch_size} ')
|
2059
2052
|
|
2060
|
-
files_processed = 0
|
2061
2053
|
for i in range(0, stack.shape[0], batch_size):
|
2062
2054
|
mask_stack = []
|
2063
|
-
start = time.time()
|
2064
|
-
|
2065
2055
|
if stack.shape[3] == 1:
|
2066
2056
|
batch = stack[i: i+batch_size, :, :, [0,0]].astype(stack.dtype)
|
2067
2057
|
else:
|
@@ -2072,7 +2062,7 @@ def generate_cellpose_masks(src, settings, object_type):
|
|
2072
2062
|
if not settings['plot']:
|
2073
2063
|
batch, batch_filenames = _check_masks(batch, batch_filenames, output_folder)
|
2074
2064
|
if batch.size == 0:
|
2075
|
-
print(f'Processing {file_index}/{len(paths)}: Images/npz {batch.shape[0]}')
|
2065
|
+
#print(f'Processing {file_index}/{len(paths)}: Images/npz {batch.shape[0]}')
|
2076
2066
|
continue
|
2077
2067
|
|
2078
2068
|
batch = prepare_batch_for_cellpose(batch)
|
@@ -2083,8 +2073,8 @@ def generate_cellpose_masks(src, settings, object_type):
|
|
2083
2073
|
save_path = os.path.join(movie_path, f'timelapse_{object_type}_{name}.mp4')
|
2084
2074
|
_npz_to_movie(batch, batch_filenames, save_path, fps=2)
|
2085
2075
|
|
2086
|
-
if settings['verbose']:
|
2087
|
-
print(f'Processing {file_index}/{len(paths)}: Images/npz {batch.shape[0]}')
|
2076
|
+
#if settings['verbose']:
|
2077
|
+
#print(f'Processing {file_index}/{len(paths)}: Images/npz {batch.shape[0]}')
|
2088
2078
|
|
2089
2079
|
#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
2080
|
# 'sharpen':object_settings['diameter']/4, #recommended to be 1/4-1/8 diameter of cells in pixels
|
@@ -2202,16 +2192,8 @@ def generate_cellpose_masks(src, settings, object_type):
|
|
2202
2192
|
|
2203
2193
|
average_sizes.append(average_obj_size)
|
2204
2194
|
overall_average_size = np.mean(average_sizes) if len(average_sizes) > 0 else 0
|
2195
|
+
print(f'object_size:{object_type}: {overall_average_size:.3f} px2')
|
2205
2196
|
|
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
2197
|
if not timelapse:
|
2216
2198
|
if settings['plot']:
|
2217
2199
|
plot_masks(batch, mask_stack, flows, figuresize=figuresize, cmap='inferno', nr=batch_size)
|
@@ -2222,7 +2204,12 @@ def generate_cellpose_masks(src, settings, object_type):
|
|
2222
2204
|
np.save(output_filename, mask)
|
2223
2205
|
mask_stack = []
|
2224
2206
|
batch_filenames = []
|
2225
|
-
|
2207
|
+
stop = time.time()
|
2208
|
+
duration = (stop - start)
|
2209
|
+
time_ls.append(duration)
|
2210
|
+
files_processed = file_index+1
|
2211
|
+
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')
|
2212
|
+
#gc.collect()
|
2226
2213
|
torch.cuda.empty_cache()
|
2227
2214
|
return
|
2228
2215
|
|
@@ -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()
|