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.
Files changed (125) hide show
  1. {spacr-0.2.4/spacr.egg-info → spacr-0.2.5}/PKG-INFO +5 -1
  2. {spacr-0.2.4 → spacr-0.2.5}/setup.py +6 -2
  3. {spacr-0.2.4 → spacr-0.2.5}/spacr/core.py +56 -67
  4. {spacr-0.2.4 → spacr-0.2.5}/spacr/gui.py +20 -38
  5. spacr-0.2.5/spacr/gui_core.py +696 -0
  6. {spacr-0.2.4 → spacr-0.2.5}/spacr/gui_elements.py +309 -59
  7. spacr-0.2.5/spacr/gui_utils.py +640 -0
  8. {spacr-0.2.4 → spacr-0.2.5}/spacr/io.py +42 -46
  9. {spacr-0.2.4 → spacr-0.2.5}/spacr/measure.py +198 -151
  10. {spacr-0.2.4 → spacr-0.2.5}/spacr/plot.py +108 -42
  11. spacr-0.2.5/spacr/resources/font/open_sans/OFL.txt +93 -0
  12. spacr-0.2.5/spacr/resources/font/open_sans/OpenSans-Italic-VariableFont_wdth,wght.ttf +0 -0
  13. spacr-0.2.5/spacr/resources/font/open_sans/OpenSans-VariableFont_wdth,wght.ttf +0 -0
  14. spacr-0.2.5/spacr/resources/font/open_sans/README.txt +100 -0
  15. spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans-Bold.ttf +0 -0
  16. spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans-BoldItalic.ttf +0 -0
  17. spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans-ExtraBold.ttf +0 -0
  18. spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans-ExtraBoldItalic.ttf +0 -0
  19. spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans-Italic.ttf +0 -0
  20. spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans-Light.ttf +0 -0
  21. spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans-LightItalic.ttf +0 -0
  22. spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans-Medium.ttf +0 -0
  23. spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans-MediumItalic.ttf +0 -0
  24. spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans-Regular.ttf +0 -0
  25. spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans-SemiBold.ttf +0 -0
  26. spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans-SemiBoldItalic.ttf +0 -0
  27. spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_Condensed-Bold.ttf +0 -0
  28. spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_Condensed-BoldItalic.ttf +0 -0
  29. spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_Condensed-ExtraBold.ttf +0 -0
  30. spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_Condensed-ExtraBoldItalic.ttf +0 -0
  31. spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_Condensed-Italic.ttf +0 -0
  32. spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_Condensed-Light.ttf +0 -0
  33. spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_Condensed-LightItalic.ttf +0 -0
  34. spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_Condensed-Medium.ttf +0 -0
  35. spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_Condensed-MediumItalic.ttf +0 -0
  36. spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_Condensed-Regular.ttf +0 -0
  37. spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_Condensed-SemiBold.ttf +0 -0
  38. spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_Condensed-SemiBoldItalic.ttf +0 -0
  39. spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-Bold.ttf +0 -0
  40. spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-BoldItalic.ttf +0 -0
  41. spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-ExtraBold.ttf +0 -0
  42. spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-ExtraBoldItalic.ttf +0 -0
  43. spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-Italic.ttf +0 -0
  44. spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-Light.ttf +0 -0
  45. spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-LightItalic.ttf +0 -0
  46. spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-Medium.ttf +0 -0
  47. spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-MediumItalic.ttf +0 -0
  48. spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-Regular.ttf +0 -0
  49. spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-SemiBold.ttf +0 -0
  50. spacr-0.2.5/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-SemiBoldItalic.ttf +0 -0
  51. spacr-0.2.5/spacr/resources/icons/logo.pdf +2786 -6
  52. spacr-0.2.5/spacr/resources/icons/logo_spacr.png +0 -0
  53. {spacr-0.2.4 → spacr-0.2.5}/spacr/settings.py +11 -83
  54. {spacr-0.2.4 → spacr-0.2.5}/spacr/utils.py +13 -33
  55. {spacr-0.2.4 → spacr-0.2.5/spacr.egg-info}/PKG-INFO +5 -1
  56. spacr-0.2.5/spacr.egg-info/SOURCES.txt +120 -0
  57. {spacr-0.2.4 → spacr-0.2.5}/spacr.egg-info/requires.txt +4 -0
  58. spacr-0.2.4/spacr/gui_core.py +0 -795
  59. spacr-0.2.4/spacr/gui_utils.py +0 -352
  60. spacr-0.2.4/spacr.egg-info/SOURCES.txt +0 -78
  61. {spacr-0.2.4 → spacr-0.2.5}/LICENSE +0 -0
  62. {spacr-0.2.4 → spacr-0.2.5}/MANIFEST.in +0 -0
  63. {spacr-0.2.4 → spacr-0.2.5}/README.rst +0 -0
  64. {spacr-0.2.4 → spacr-0.2.5}/setup.cfg +0 -0
  65. {spacr-0.2.4 → spacr-0.2.5}/spacr/__init__.py +0 -0
  66. {spacr-0.2.4 → spacr-0.2.5}/spacr/__main__.py +0 -0
  67. {spacr-0.2.4 → spacr-0.2.5}/spacr/app_annotate.py +0 -0
  68. {spacr-0.2.4 → spacr-0.2.5}/spacr/app_classify.py +0 -0
  69. {spacr-0.2.4 → spacr-0.2.5}/spacr/app_make_masks.py +0 -0
  70. {spacr-0.2.4 → spacr-0.2.5}/spacr/app_mask.py +0 -0
  71. {spacr-0.2.4 → spacr-0.2.5}/spacr/app_measure.py +0 -0
  72. {spacr-0.2.4 → spacr-0.2.5}/spacr/app_sequencing.py +0 -0
  73. {spacr-0.2.4 → spacr-0.2.5}/spacr/app_umap.py +0 -0
  74. {spacr-0.2.4 → spacr-0.2.5}/spacr/chris.py +0 -0
  75. {spacr-0.2.4 → spacr-0.2.5}/spacr/deep_spacr.py +0 -0
  76. {spacr-0.2.4 → spacr-0.2.5}/spacr/graph_learning.py +0 -0
  77. {spacr-0.2.4 → spacr-0.2.5}/spacr/logger.py +0 -0
  78. {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/abort.png +0 -0
  79. {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/annotate.png +0 -0
  80. {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/cellpose_all.png +0 -0
  81. {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/cellpose_masks.png +0 -0
  82. {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/classify.png +0 -0
  83. {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/default.png +0 -0
  84. {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/download.png +0 -0
  85. /spacr-0.2.4/spacr/resources/icons/logo_spacr.png → /spacr-0.2.5/spacr/resources/icons/logo_spacr_1.png +0 -0
  86. {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/make_masks.png +0 -0
  87. {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/map_barcodes.png +0 -0
  88. {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/mask.png +0 -0
  89. {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/measure.png +0 -0
  90. {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/ml_analyze.png +0 -0
  91. {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/recruitment.png +0 -0
  92. {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/regression.png +0 -0
  93. {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/run.png +0 -0
  94. {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/sequencing.png +0 -0
  95. {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/settings.png +0 -0
  96. {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/spacr_logo_rotation.gif +0 -0
  97. {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/train_cellpose.png +0 -0
  98. {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/icons/umap.png +0 -0
  99. {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/models/cp/toxo_plaque_cyto_e25000_X1120_Y1120.CP_model +0 -0
  100. {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/models/cp/toxo_plaque_cyto_e25000_X1120_Y1120.CP_model_settings.csv +0 -0
  101. {spacr-0.2.4 → spacr-0.2.5}/spacr/resources/models/cp/toxo_pv_lumen.CP_model +0 -0
  102. {spacr-0.2.4 → spacr-0.2.5}/spacr/sequencing.py +0 -0
  103. {spacr-0.2.4 → spacr-0.2.5}/spacr/sim.py +0 -0
  104. {spacr-0.2.4 → spacr-0.2.5}/spacr/sim_app.py +0 -0
  105. {spacr-0.2.4 → spacr-0.2.5}/spacr/timelapse.py +0 -0
  106. {spacr-0.2.4 → spacr-0.2.5}/spacr/version.py +0 -0
  107. {spacr-0.2.4 → spacr-0.2.5}/spacr.egg-info/dependency_links.txt +0 -0
  108. {spacr-0.2.4 → spacr-0.2.5}/spacr.egg-info/entry_points.txt +0 -0
  109. {spacr-0.2.4 → spacr-0.2.5}/spacr.egg-info/top_level.txt +0 -0
  110. {spacr-0.2.4 → spacr-0.2.5}/tests/test_annotate_app.py +0 -0
  111. {spacr-0.2.4 → spacr-0.2.5}/tests/test_core.py +0 -0
  112. {spacr-0.2.4 → spacr-0.2.5}/tests/test_gui_classify_app.py +0 -0
  113. {spacr-0.2.4 → spacr-0.2.5}/tests/test_gui_mask_app.py +0 -0
  114. {spacr-0.2.4 → spacr-0.2.5}/tests/test_gui_measure_app.py +0 -0
  115. {spacr-0.2.4 → spacr-0.2.5}/tests/test_gui_sim_app.py +0 -0
  116. {spacr-0.2.4 → spacr-0.2.5}/tests/test_gui_utils.py +0 -0
  117. {spacr-0.2.4 → spacr-0.2.5}/tests/test_io.py +0 -0
  118. {spacr-0.2.4 → spacr-0.2.5}/tests/test_mask_app.py +0 -0
  119. {spacr-0.2.4 → spacr-0.2.5}/tests/test_measure.py +0 -0
  120. {spacr-0.2.4 → spacr-0.2.5}/tests/test_plot.py +0 -0
  121. {spacr-0.2.4 → spacr-0.2.5}/tests/test_sim.py +0 -0
  122. {spacr-0.2.4 → spacr-0.2.5}/tests/test_timelapse.py +0 -0
  123. {spacr-0.2.4 → spacr-0.2.5}/tests/test_train.py +0 -0
  124. {spacr-0.2.4 → spacr-0.2.5}/tests/test_umap.py +0 -0
  125. {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.4
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.4",
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 plot_merged, plot_arrays
1699
- from .utils import _pivot_counts_table, check_mask_folder, adjust_cell_masks
1700
- from .settings import set_default_settings_preprocess_generate_masks, set_default_plot_merge_settings
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
- #image_folder = os.path.join(src, 'stack')
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
- plot_settings['nr'] = len(os.path.join(src,'merged'))
1794
+ settings['examples_to_plot'] = len(os.path.join(src,'merged'))
1803
1795
 
1804
1796
  try:
1805
- fig = plot_merged(src=os.path.join(src,'merged'), settings=plot_settings)
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 = {} # Initialize main_buttons dictionary here
22
- self.additional_buttons = {} # Initialize additional_buttons dictionary here
20
+ self.main_buttons = {}
21
+ self.additional_buttons = {}
23
22
 
24
23
  self.main_gui_apps = {
25
- "Mask": (lambda frame: initiate_root(frame, 'mask'), "Generate cellpose masks for cells, nuclei and pathogen images."),
26
- "Measure": (lambda frame: initiate_root(frame, 'measure'), "Measure single object intensity and morphological feature. Crop and save single object image"),
27
- "Annotate": (lambda frame: initiate_root(frame, 'annotate'), "Annotation single object images on a grid. Annotations are saved to database."),
28
- "Make Masks": (lambda frame: initiate_root(frame, 'make_masks'), "Adjust pre-existing Cellpose models to your specific dataset for improved performance"),
29
- "Classify": (lambda frame: initiate_root(frame, 'classify'), "Train Torch Convolutional Neural Networks (CNNs) or Transformers to classify single object images."),
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(frame, 'sequencing'), "Analyze sequencing data."),
34
- "Umap": (lambda frame: initiate_root(frame, 'umap'), "Generate UMAP embeddings with datapoints represented as images."),
35
- "Train Cellpose": (lambda frame: initiate_root(frame, 'train_cellpose'), "Train custom Cellpose models."),
36
- "ML Analyze": (lambda frame: initiate_root(frame, 'ml_analyze'), "Machine learning analysis of data."),
37
- "Cellpose Masks": (lambda frame: initiate_root(frame, 'cellpose_masks'), "Generate Cellpose masks."),
38
- "Cellpose All": (lambda frame: initiate_root(frame, 'cellpose_all'), "Run Cellpose on all images."),
39
- "Map Barcodes": (lambda frame: initiate_root(frame, 'map_barcodes'), "Map barcodes to data."),
40
- "Regression": (lambda frame: initiate_root(frame, 'regression'), "Perform regression analysis."),
41
- "Recruitment": (lambda frame: initiate_root(frame, 'recruitment'), "Analyze recruitment data.")
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) # Prevent the frame from resizing based on its content
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() # Ensure the label updates immediately
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() # Ensure the label updates immediately
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()