spacr 0.2.81__tar.gz → 0.3.1__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 (180) hide show
  1. spacr-0.3.1/MANIFEST.in +5 -0
  2. {spacr-0.2.81/spacr.egg-info → spacr-0.3.1}/PKG-INFO +9 -1
  3. {spacr-0.2.81 → spacr-0.3.1}/setup.py +12 -3
  4. {spacr-0.2.81 → spacr-0.3.1}/spacr/__init__.py +2 -1
  5. {spacr-0.2.81 → spacr-0.3.1}/spacr/core.py +107 -12
  6. {spacr-0.2.81 → spacr-0.3.1}/spacr/gui.py +3 -2
  7. {spacr-0.2.81 → spacr-0.3.1}/spacr/gui_core.py +8 -4
  8. {spacr-0.2.81 → spacr-0.3.1}/spacr/gui_utils.py +4 -1
  9. {spacr-0.2.81 → spacr-0.3.1}/spacr/io.py +13 -13
  10. {spacr-0.2.81 → spacr-0.3.1}/spacr/measure.py +4 -4
  11. spacr-0.3.1/spacr/mediar.py +364 -0
  12. {spacr-0.2.81 → spacr-0.3.1}/spacr/plot.py +5 -2
  13. spacr-0.3.1/spacr/resources/MEDIAR/.git +1 -0
  14. spacr-0.3.1/spacr/resources/MEDIAR/.gitignore +18 -0
  15. spacr-0.3.1/spacr/resources/MEDIAR/LICENSE +21 -0
  16. spacr-0.3.1/spacr/resources/MEDIAR/README.md +189 -0
  17. spacr-0.3.1/spacr/resources/MEDIAR/SetupDict.py +39 -0
  18. spacr-0.3.1/spacr/resources/MEDIAR/config/baseline.json +60 -0
  19. spacr-0.3.1/spacr/resources/MEDIAR/config/mediar_example.json +72 -0
  20. spacr-0.3.1/spacr/resources/MEDIAR/config/pred/pred_mediar.json +17 -0
  21. spacr-0.3.1/spacr/resources/MEDIAR/config/step1_pretraining/phase1.json +55 -0
  22. spacr-0.3.1/spacr/resources/MEDIAR/config/step1_pretraining/phase2.json +58 -0
  23. spacr-0.3.1/spacr/resources/MEDIAR/config/step2_finetuning/finetuning1.json +66 -0
  24. spacr-0.3.1/spacr/resources/MEDIAR/config/step2_finetuning/finetuning2.json +66 -0
  25. spacr-0.3.1/spacr/resources/MEDIAR/config/step3_prediction/base_prediction.json +16 -0
  26. spacr-0.3.1/spacr/resources/MEDIAR/config/step3_prediction/ensemble_tta.json +23 -0
  27. spacr-0.3.1/spacr/resources/MEDIAR/core/BasePredictor.py +120 -0
  28. spacr-0.3.1/spacr/resources/MEDIAR/core/BaseTrainer.py +240 -0
  29. spacr-0.3.1/spacr/resources/MEDIAR/core/Baseline/Predictor.py +59 -0
  30. spacr-0.3.1/spacr/resources/MEDIAR/core/Baseline/Trainer.py +113 -0
  31. spacr-0.3.1/spacr/resources/MEDIAR/core/Baseline/__init__.py +2 -0
  32. spacr-0.3.1/spacr/resources/MEDIAR/core/Baseline/utils.py +80 -0
  33. spacr-0.3.1/spacr/resources/MEDIAR/core/MEDIAR/EnsemblePredictor.py +105 -0
  34. spacr-0.3.1/spacr/resources/MEDIAR/core/MEDIAR/Predictor.py +234 -0
  35. spacr-0.3.1/spacr/resources/MEDIAR/core/MEDIAR/Trainer.py +172 -0
  36. spacr-0.3.1/spacr/resources/MEDIAR/core/MEDIAR/__init__.py +3 -0
  37. spacr-0.3.1/spacr/resources/MEDIAR/core/MEDIAR/utils.py +429 -0
  38. spacr-0.3.1/spacr/resources/MEDIAR/core/__init__.py +2 -0
  39. spacr-0.3.1/spacr/resources/MEDIAR/core/utils.py +40 -0
  40. spacr-0.3.1/spacr/resources/MEDIAR/evaluate.py +71 -0
  41. spacr-0.3.1/spacr/resources/MEDIAR/generate_mapping.py +121 -0
  42. spacr-0.3.1/spacr/resources/MEDIAR/image/examples/img1.tiff +0 -0
  43. spacr-0.3.1/spacr/resources/MEDIAR/image/examples/img2.tif +0 -0
  44. spacr-0.3.1/spacr/resources/MEDIAR/image/failure_cases.png +0 -0
  45. spacr-0.3.1/spacr/resources/MEDIAR/image/mediar_framework.png +0 -0
  46. spacr-0.3.1/spacr/resources/MEDIAR/image/mediar_model.PNG +0 -0
  47. spacr-0.3.1/spacr/resources/MEDIAR/image/mediar_results.png +0 -0
  48. spacr-0.3.1/spacr/resources/MEDIAR/main.py +125 -0
  49. spacr-0.3.1/spacr/resources/MEDIAR/predict.py +70 -0
  50. spacr-0.3.1/spacr/resources/MEDIAR/requirements.txt +14 -0
  51. spacr-0.3.1/spacr/resources/MEDIAR/train_tools/__init__.py +3 -0
  52. spacr-0.3.1/spacr/resources/MEDIAR/train_tools/data_utils/__init__.py +1 -0
  53. spacr-0.3.1/spacr/resources/MEDIAR/train_tools/data_utils/custom/CellAware.py +88 -0
  54. spacr-0.3.1/spacr/resources/MEDIAR/train_tools/data_utils/custom/LoadImage.py +161 -0
  55. spacr-0.3.1/spacr/resources/MEDIAR/train_tools/data_utils/custom/NormalizeImage.py +77 -0
  56. spacr-0.3.1/spacr/resources/MEDIAR/train_tools/data_utils/custom/__init__.py +3 -0
  57. spacr-0.3.1/spacr/resources/MEDIAR/train_tools/data_utils/custom/modalities.pkl +0 -0
  58. spacr-0.3.1/spacr/resources/MEDIAR/train_tools/data_utils/datasetter.py +208 -0
  59. spacr-0.3.1/spacr/resources/MEDIAR/train_tools/data_utils/transforms.py +148 -0
  60. spacr-0.3.1/spacr/resources/MEDIAR/train_tools/data_utils/utils.py +84 -0
  61. spacr-0.3.1/spacr/resources/MEDIAR/train_tools/measures.py +200 -0
  62. spacr-0.3.1/spacr/resources/MEDIAR/train_tools/models/MEDIARFormer.py +102 -0
  63. spacr-0.3.1/spacr/resources/MEDIAR/train_tools/models/__init__.py +1 -0
  64. spacr-0.3.1/spacr/resources/MEDIAR/train_tools/utils.py +70 -0
  65. spacr-0.3.1/spacr/resources/MEDIAR_weights/.DS_Store +0 -0
  66. spacr-0.3.1/spacr/resources/icons/.DS_Store +0 -0
  67. spacr-0.3.1/spacr/resources/icons/plaque.png +0 -0
  68. spacr-0.3.1/spacr/resources/images/plate1_E01_T0001F001L01A01Z01C02.tif +0 -0
  69. spacr-0.3.1/spacr/resources/images/plate1_E01_T0001F001L01A02Z01C01.tif +0 -0
  70. spacr-0.3.1/spacr/resources/images/plate1_E01_T0001F001L01A03Z01C03.tif +0 -0
  71. {spacr-0.2.81 → spacr-0.3.1}/spacr/settings.py +3 -1
  72. {spacr-0.2.81 → spacr-0.3.1}/spacr/utils.py +15 -13
  73. {spacr-0.2.81 → spacr-0.3.1/spacr.egg-info}/PKG-INFO +9 -1
  74. {spacr-0.2.81 → spacr-0.3.1}/spacr.egg-info/SOURCES.txt +59 -1
  75. {spacr-0.2.81 → spacr-0.3.1}/spacr.egg-info/requires.txt +8 -0
  76. spacr-0.2.81/MANIFEST.in +0 -1
  77. spacr-0.2.81/spacr/resources/icons/spacr_logo_rotation.gif +0 -0
  78. {spacr-0.2.81 → spacr-0.3.1}/LICENSE +0 -0
  79. {spacr-0.2.81 → spacr-0.3.1}/README.rst +0 -0
  80. {spacr-0.2.81 → spacr-0.3.1}/setup.cfg +0 -0
  81. {spacr-0.2.81 → spacr-0.3.1}/spacr/__main__.py +0 -0
  82. {spacr-0.2.81 → spacr-0.3.1}/spacr/app_annotate.py +0 -0
  83. {spacr-0.2.81 → spacr-0.3.1}/spacr/app_classify.py +0 -0
  84. {spacr-0.2.81 → spacr-0.3.1}/spacr/app_make_masks.py +0 -0
  85. {spacr-0.2.81 → spacr-0.3.1}/spacr/app_mask.py +0 -0
  86. {spacr-0.2.81 → spacr-0.3.1}/spacr/app_measure.py +0 -0
  87. {spacr-0.2.81 → spacr-0.3.1}/spacr/app_sequencing.py +0 -0
  88. {spacr-0.2.81 → spacr-0.3.1}/spacr/app_umap.py +0 -0
  89. {spacr-0.2.81 → spacr-0.3.1}/spacr/deep_spacr.py +0 -0
  90. {spacr-0.2.81 → spacr-0.3.1}/spacr/gui_elements.py +0 -0
  91. {spacr-0.2.81 → spacr-0.3.1}/spacr/logger.py +0 -0
  92. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/OFL.txt +0 -0
  93. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/OpenSans-Italic-VariableFont_wdth,wght.ttf +0 -0
  94. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/OpenSans-VariableFont_wdth,wght.ttf +0 -0
  95. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/README.txt +0 -0
  96. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/static/OpenSans-Bold.ttf +0 -0
  97. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/static/OpenSans-BoldItalic.ttf +0 -0
  98. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/static/OpenSans-ExtraBold.ttf +0 -0
  99. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/static/OpenSans-ExtraBoldItalic.ttf +0 -0
  100. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/static/OpenSans-Italic.ttf +0 -0
  101. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/static/OpenSans-Light.ttf +0 -0
  102. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/static/OpenSans-LightItalic.ttf +0 -0
  103. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/static/OpenSans-Medium.ttf +0 -0
  104. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/static/OpenSans-MediumItalic.ttf +0 -0
  105. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/static/OpenSans-Regular.ttf +0 -0
  106. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/static/OpenSans-SemiBold.ttf +0 -0
  107. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/static/OpenSans-SemiBoldItalic.ttf +0 -0
  108. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/static/OpenSans_Condensed-Bold.ttf +0 -0
  109. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/static/OpenSans_Condensed-BoldItalic.ttf +0 -0
  110. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/static/OpenSans_Condensed-ExtraBold.ttf +0 -0
  111. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/static/OpenSans_Condensed-ExtraBoldItalic.ttf +0 -0
  112. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/static/OpenSans_Condensed-Italic.ttf +0 -0
  113. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/static/OpenSans_Condensed-Light.ttf +0 -0
  114. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/static/OpenSans_Condensed-LightItalic.ttf +0 -0
  115. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/static/OpenSans_Condensed-Medium.ttf +0 -0
  116. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/static/OpenSans_Condensed-MediumItalic.ttf +0 -0
  117. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/static/OpenSans_Condensed-Regular.ttf +0 -0
  118. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/static/OpenSans_Condensed-SemiBold.ttf +0 -0
  119. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/static/OpenSans_Condensed-SemiBoldItalic.ttf +0 -0
  120. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-Bold.ttf +0 -0
  121. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-BoldItalic.ttf +0 -0
  122. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-ExtraBold.ttf +0 -0
  123. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-ExtraBoldItalic.ttf +0 -0
  124. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-Italic.ttf +0 -0
  125. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-Light.ttf +0 -0
  126. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-LightItalic.ttf +0 -0
  127. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-Medium.ttf +0 -0
  128. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-MediumItalic.ttf +0 -0
  129. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-Regular.ttf +0 -0
  130. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-SemiBold.ttf +0 -0
  131. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-SemiBoldItalic.ttf +0 -0
  132. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/icons/abort.png +0 -0
  133. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/icons/annotate.png +0 -0
  134. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/icons/cellpose_all.png +0 -0
  135. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/icons/cellpose_masks.png +0 -0
  136. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/icons/classify.png +0 -0
  137. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/icons/default.png +0 -0
  138. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/icons/download.png +0 -0
  139. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/icons/logo.pdf +0 -0
  140. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/icons/logo_spacr.png +0 -0
  141. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/icons/logo_spacr_1.png +0 -0
  142. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/icons/make_masks.png +0 -0
  143. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/icons/map_barcodes.png +0 -0
  144. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/icons/mask.png +0 -0
  145. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/icons/measure.png +0 -0
  146. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/icons/ml_analyze.png +0 -0
  147. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/icons/recruitment.png +0 -0
  148. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/icons/regression.png +0 -0
  149. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/icons/run.png +0 -0
  150. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/icons/sequencing.png +0 -0
  151. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/icons/settings.png +0 -0
  152. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/icons/train_cellpose.png +0 -0
  153. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/icons/umap.png +0 -0
  154. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/models/cp/toxo_plaque_cyto_e25000_X1120_Y1120.CP_model +0 -0
  155. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/models/cp/toxo_plaque_cyto_e25000_X1120_Y1120.CP_model_settings.csv +0 -0
  156. {spacr-0.2.81 → spacr-0.3.1}/spacr/resources/models/cp/toxo_pv_lumen.CP_model +0 -0
  157. {spacr-0.2.81 → spacr-0.3.1}/spacr/sequencing.py +0 -0
  158. {spacr-0.2.81 → spacr-0.3.1}/spacr/sim.py +0 -0
  159. {spacr-0.2.81 → spacr-0.3.1}/spacr/sim_app.py +0 -0
  160. {spacr-0.2.81 → spacr-0.3.1}/spacr/timelapse.py +0 -0
  161. {spacr-0.2.81 → spacr-0.3.1}/spacr/version.py +0 -0
  162. {spacr-0.2.81 → spacr-0.3.1}/spacr.egg-info/dependency_links.txt +0 -0
  163. {spacr-0.2.81 → spacr-0.3.1}/spacr.egg-info/entry_points.txt +0 -0
  164. {spacr-0.2.81 → spacr-0.3.1}/spacr.egg-info/top_level.txt +0 -0
  165. {spacr-0.2.81 → spacr-0.3.1}/tests/test_annotate_app.py +0 -0
  166. {spacr-0.2.81 → spacr-0.3.1}/tests/test_core.py +0 -0
  167. {spacr-0.2.81 → spacr-0.3.1}/tests/test_gui_classify_app.py +0 -0
  168. {spacr-0.2.81 → spacr-0.3.1}/tests/test_gui_mask_app.py +0 -0
  169. {spacr-0.2.81 → spacr-0.3.1}/tests/test_gui_measure_app.py +0 -0
  170. {spacr-0.2.81 → spacr-0.3.1}/tests/test_gui_sim_app.py +0 -0
  171. {spacr-0.2.81 → spacr-0.3.1}/tests/test_gui_utils.py +0 -0
  172. {spacr-0.2.81 → spacr-0.3.1}/tests/test_io.py +0 -0
  173. {spacr-0.2.81 → spacr-0.3.1}/tests/test_mask_app.py +0 -0
  174. {spacr-0.2.81 → spacr-0.3.1}/tests/test_measure.py +0 -0
  175. {spacr-0.2.81 → spacr-0.3.1}/tests/test_plot.py +0 -0
  176. {spacr-0.2.81 → spacr-0.3.1}/tests/test_sim.py +0 -0
  177. {spacr-0.2.81 → spacr-0.3.1}/tests/test_timelapse.py +0 -0
  178. {spacr-0.2.81 → spacr-0.3.1}/tests/test_train.py +0 -0
  179. {spacr-0.2.81 → spacr-0.3.1}/tests/test_umap.py +0 -0
  180. {spacr-0.2.81 → spacr-0.3.1}/tests/test_utils.py +0 -0
@@ -0,0 +1,5 @@
1
+ recursive-include spacr/resources/models/cp *
2
+ recursive-include spacr/resources/icons *
3
+ recursive-include spacr/resources/font *
4
+ recursive-include spacr/resources/MEDIAR *
5
+ recursive-include spacr/resources/MEDIAR_weights *
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: spacr
3
- Version: 0.2.81
3
+ Version: 0.3.1
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
@@ -50,6 +50,14 @@ Requires-Dist: rapidfuzz<4.0,>=3.9
50
50
  Requires-Dist: keyring<16.0,>=15.1
51
51
  Requires-Dist: screeninfo<1.0,>=0.8.1
52
52
  Requires-Dist: ipykernel
53
+ Requires-Dist: gdown
54
+ Requires-Dist: fastremap>=1.14.1
55
+ Requires-Dist: monai>=1.3.0
56
+ Requires-Dist: pytz>=2023.3.post1
57
+ Requires-Dist: segmentation_models_pytorch>=0.3.3
58
+ Requires-Dist: tifffile>=2023.4.12
59
+ Requires-Dist: tqdm>=4.65.0
60
+ Requires-Dist: wandb>=0.16.2
53
61
  Requires-Dist: huggingface-hub<0.25,>=0.24.0
54
62
  Provides-Extra: dev
55
63
  Requires-Dist: pytest<3.11,>=3.9; extra == "dev"
@@ -47,12 +47,20 @@ dependencies = [
47
47
  'keyring>=15.1, <16.0',
48
48
  'screeninfo>=0.8.1,<1.0',
49
49
  'ipykernel',
50
+ 'gdown',
51
+ 'fastremap>=1.14.1',
52
+ 'monai>=1.3.0',
53
+ 'pytz>=2023.3.post1',
54
+ 'segmentation_models_pytorch>=0.3.3',
55
+ 'tifffile>=2023.4.12',
56
+ 'tqdm>=4.65.0',
57
+ 'wandb>=0.16.2',
50
58
  'huggingface-hub>=0.24.0,<0.25'
51
59
  ]
52
60
 
53
61
  setup(
54
62
  name="spacr",
55
- version="0.2.81",
63
+ version="0.3.01",
56
64
  author="Einar Birnir Olafsson",
57
65
  author_email="olafsson@med.umich.com",
58
66
  description="Spatial phenotype analysis of crisp screens (SpaCr)",
@@ -60,7 +68,7 @@ setup(
60
68
  url="https://github.com/EinarOlafsson/spacr",
61
69
  packages=find_packages(exclude=["tests.*", "tests"]),
62
70
  include_package_data=True,
63
- package_data={'spacr': ['resources/models/cp/*', 'resources/icons/*', 'resources/font/**/*'],},
71
+ package_data={'spacr': ['resources/models/cp/*', 'resources/icons/*', 'resources/font/**/*', 'resources/MEDIAR/**/*', 'resources/MEDIAR_weights/*', 'resources/images/*'],},
64
72
  install_requires=dependencies,
65
73
  entry_points={
66
74
  'console_scripts': [
@@ -100,4 +108,5 @@ for dep in deps:
100
108
  try:
101
109
  subprocess.run(['pip', 'install', dep], check=True)
102
110
  except subprocess.CalledProcessError:
103
- pass
111
+ pass
112
+
@@ -23,9 +23,9 @@ from . import app_measure
23
23
  from . import app_classify
24
24
  from . import app_sequencing
25
25
  from . import app_umap
26
+ from . import mediar
26
27
  from . import logger
27
28
 
28
-
29
29
  __all__ = [
30
30
  "core",
31
31
  "io",
@@ -48,6 +48,7 @@ __all__ = [
48
48
  "app_classify",
49
49
  "app_sequencing",
50
50
  "app_umap",
51
+ "mediar",
51
52
  "logger"
52
53
  ]
53
54
 
@@ -50,8 +50,6 @@ import random
50
50
  from PIL import Image
51
51
  from torchvision.transforms import ToTensor
52
52
 
53
-
54
-
55
53
  def analyze_plaques(folder):
56
54
  summary_data = []
57
55
  details_data = []
@@ -1674,7 +1672,10 @@ def preprocess_generate_masks(src, settings={}):
1674
1672
  time_ls=[]
1675
1673
  if check_mask_folder(src, 'cell_mask_stack'):
1676
1674
  start = time.time()
1677
- generate_cellpose_masks(mask_src, settings, 'cell')
1675
+ if settings['segmentation_mode'] == 'cellpose':
1676
+ generate_cellpose_masks(mask_src, settings, 'cell')
1677
+ elif settings['segmentation_mode'] == 'mediar':
1678
+ generate_mediar_masks(mask_src, settings, 'cell')
1678
1679
  stop = time.time()
1679
1680
  duration = (stop - start)
1680
1681
  time_ls.append(duration)
@@ -1685,7 +1686,10 @@ def preprocess_generate_masks(src, settings={}):
1685
1686
  time_ls=[]
1686
1687
  if check_mask_folder(src, 'nucleus_mask_stack'):
1687
1688
  start = time.time()
1688
- generate_cellpose_masks(mask_src, settings, 'nucleus')
1689
+ if settings['segmentation_mode'] == 'cellpose':
1690
+ generate_cellpose_masks(mask_src, settings, 'nucleus')
1691
+ elif settings['segmentation_mode'] == 'mediar':
1692
+ generate_mediar_masks(mask_src, settings, 'nucleus')
1689
1693
  stop = time.time()
1690
1694
  duration = (stop - start)
1691
1695
  time_ls.append(duration)
@@ -1696,7 +1700,10 @@ def preprocess_generate_masks(src, settings={}):
1696
1700
  time_ls=[]
1697
1701
  if check_mask_folder(src, 'pathogen_mask_stack'):
1698
1702
  start = time.time()
1699
- generate_cellpose_masks(mask_src, settings, 'pathogen')
1703
+ if settings['segmentation_mode'] == 'cellpose':
1704
+ generate_cellpose_masks(mask_src, settings, 'pathogen')
1705
+ elif settings['segmentation_mode'] == 'mediar':
1706
+ generate_mediar_masks(mask_src, settings, 'pathogen')
1700
1707
  stop = time.time()
1701
1708
  duration = (stop - start)
1702
1709
  time_ls.append(duration)
@@ -1750,7 +1757,7 @@ def preprocess_generate_masks(src, settings={}):
1750
1757
  files_processed = i+1
1751
1758
  files_to_process = settings['examples_to_plot']
1752
1759
  print_progress(files_processed, files_to_process, n_jobs=1, time_ls=time_ls, batch_size=None, operation_type="Plot mask outlines")
1753
- print("Successfully completed run")
1760
+
1754
1761
  except Exception as e:
1755
1762
  print(f'Failed to plot image mask overly. Error: {e}')
1756
1763
  else:
@@ -1898,7 +1905,7 @@ def all_elements_match(list1, list2):
1898
1905
  # Check if all elements in list1 are in list2
1899
1906
  return all(element in list2 for element in list1)
1900
1907
 
1901
- def prepare_batch_for_cellpose(batch):
1908
+ def prepare_batch_for_segmentation(batch):
1902
1909
  # Ensure the batch is of dtype float32
1903
1910
  if batch.dtype != np.float32:
1904
1911
  batch = batch.astype(np.float32)
@@ -2021,7 +2028,7 @@ def generate_cellpose_masks(src, settings, object_type):
2021
2028
  if batch.size == 0:
2022
2029
  continue
2023
2030
 
2024
- batch = prepare_batch_for_cellpose(batch)
2031
+ batch = prepare_batch_for_segmentation(batch)
2025
2032
 
2026
2033
  if timelapse:
2027
2034
  movie_path = os.path.join(os.path.dirname(src), 'movies')
@@ -2180,7 +2187,7 @@ def generate_masks_from_imgs(src, model, model_name, batch_size, diameter, cellp
2180
2187
  image_files = all_image_files[i:i+batch_size]
2181
2188
 
2182
2189
  if normalize:
2183
- images, _, image_names, _ = _load_normalized_images_and_labels(image_files, None, channels, percentiles, circular, invert, plot, remove_background, background, Signal_to_noise)
2190
+ images, _, image_names, _, orig_dims = _load_normalized_images_and_labels(image_files, None, channels, percentiles, circular, invert, plot, remove_background, background, Signal_to_noise, target_height, target_width)
2184
2191
  images = [np.squeeze(img) if img.shape[-1] == 1 else img for img in images]
2185
2192
  orig_dims = [(image.shape[0], image.shape[1]) for image in images]
2186
2193
  else:
@@ -2300,7 +2307,7 @@ def compare_cellpose_masks(src, verbose=False, processes=None, save=True):
2300
2307
  from .io import _read_mask
2301
2308
 
2302
2309
  dirs = [os.path.join(src, d) for d in os.listdir(src) if os.path.isdir(os.path.join(src, d)) and d != 'results']
2303
- dirs.sort() # Optional: sort directories if needed
2310
+ dirs.sort()
2304
2311
  conditions = [os.path.basename(d) for d in dirs]
2305
2312
 
2306
2313
  # Get common files in all directories
@@ -2316,7 +2323,7 @@ def compare_cellpose_masks(src, verbose=False, processes=None, save=True):
2316
2323
 
2317
2324
  # Filter out None results (from skipped files)
2318
2325
  results = [res for res in results if res is not None]
2319
- #print(results)
2326
+ print(results)
2320
2327
  if verbose:
2321
2328
  for result in results:
2322
2329
  filename = result['filename']
@@ -3102,4 +3109,92 @@ def reducer_hyperparameter_search(settings={}, reduction_params=None, dbscan_par
3102
3109
  else:
3103
3110
  plt.show()
3104
3111
 
3105
- return
3112
+ return
3113
+
3114
+ def generate_mediar_masks(src, settings, object_type):
3115
+ """
3116
+ Generates masks using the MEDIARPredictor.
3117
+
3118
+ :param src: Source folder containing images or npz files.
3119
+ :param settings: Dictionary of settings for generating masks.
3120
+ :param object_type: Type of object to detect (e.g., 'cell', 'nucleus', etc.).
3121
+ """
3122
+ from .mediar import MEDIARPredictor
3123
+ from .io import _create_database, _save_object_counts_to_database
3124
+ from .plot import plot_masks
3125
+ from .settings import set_default_settings_preprocess_generate_masks, _get_object_settings
3126
+
3127
+ # Clear CUDA cache and check if CUDA is available
3128
+ gc.collect()
3129
+ if not torch.cuda.is_available():
3130
+ print(f'Torch CUDA is not available, using CPU')
3131
+
3132
+ # Preprocess settings
3133
+ settings = set_default_settings_preprocess_generate_masks(src, settings)
3134
+
3135
+ if settings['verbose']:
3136
+ settings_df = pd.DataFrame(list(settings.items()), columns=['setting_key', 'setting_value'])
3137
+ settings_df['setting_value'] = settings_df['setting_value'].apply(str)
3138
+ display(settings_df)
3139
+
3140
+ figuresize = 10
3141
+ timelapse = settings['timelapse']
3142
+ batch_size = settings['batch_size']
3143
+
3144
+ # Get object settings and initialize MEDIARPredictor
3145
+ mediar_predictor = MEDIARPredictor(input_path=None, output_path=None, normalize=settings['normalize'], use_tta=False)
3146
+
3147
+ # Paths to input npz files
3148
+ paths = [os.path.join(src, file) for file in os.listdir(src) if file.endswith('.npz')]
3149
+
3150
+ # Initialize a database for saving measurements
3151
+ count_loc = os.path.join(os.path.dirname(src), 'measurements', 'measurements.db')
3152
+ os.makedirs(os.path.dirname(src) + '/measurements', exist_ok=True)
3153
+ _create_database(count_loc)
3154
+
3155
+ for file_index, path in enumerate(paths):
3156
+ name = os.path.basename(path)
3157
+ name, ext = os.path.splitext(name)
3158
+ output_folder = os.path.join(os.path.dirname(path), f'{object_type}_mask_stack')
3159
+ os.makedirs(output_folder, exist_ok=True)
3160
+
3161
+ with np.load(path) as data:
3162
+ stack = data['data']
3163
+ filenames = data['filenames']
3164
+
3165
+ for i, filename in enumerate(filenames):
3166
+ output_path = os.path.join(output_folder, filename)
3167
+ if os.path.exists(output_path):
3168
+ print(f"File {filename} already exists. Skipping...")
3169
+ continue
3170
+
3171
+ # Process each batch of images in the stack
3172
+ for i in range(0, stack.shape[0], batch_size):
3173
+ batch = stack[i: i + batch_size]
3174
+ batch_filenames = filenames[i: i + batch_size]
3175
+
3176
+ # Prepare batch for MEDIARPredictor (optional)
3177
+ batch = prepare_batch_for_segmentation(batch)
3178
+
3179
+ # Predict masks using MEDIARPredictor
3180
+ predicted_masks = mediar_predictor.predict_batch(batch)
3181
+
3182
+ # Save predicted masks
3183
+ for j, mask in enumerate(predicted_masks):
3184
+ output_filename = os.path.join(output_folder, batch_filenames[j])
3185
+ mask = mask.astype(np.uint16)
3186
+ np.save(output_filename, mask)
3187
+
3188
+ # Optional: Plot the masks
3189
+ if settings['plot']:
3190
+ for idx, mask in enumerate(predicted_masks):
3191
+ plot_masks(batch[idx], mask, cmap='inferno', figuresize=figuresize)
3192
+
3193
+ # Save object counts to database
3194
+ _save_object_counts_to_database(predicted_masks, object_type, batch_filenames, count_loc)
3195
+
3196
+ # Clear CUDA cache after each file
3197
+ gc.collect()
3198
+ torch.cuda.empty_cache()
3199
+
3200
+ print("Mask generation completed.")
@@ -32,7 +32,7 @@ class MainApp(tk.Tk):
32
32
  # Set the window size to the dimensions of the monitor where it is located
33
33
  self.geometry(f"{width}x{height}")
34
34
  self.title("SpaCr GUI Collection")
35
- self.configure(bg='#333333') # Set window background to dark gray
35
+ self.configure(bg='#333333')
36
36
 
37
37
  style = ttk.Style()
38
38
  self.color_settings = set_dark_style(style, parent_frame=self)
@@ -55,7 +55,8 @@ class MainApp(tk.Tk):
55
55
  "Cellpose All": (lambda frame: initiate_root(self, 'cellpose_all'), "Run Cellpose on all images."),
56
56
  "Map Barcodes": (lambda frame: initiate_root(self, 'map_barcodes'), "Map barcodes to data."),
57
57
  "Regression": (lambda frame: initiate_root(self, 'regression'), "Perform regression analysis."),
58
- "Recruitment": (lambda frame: initiate_root(self, 'recruitment'), "Analyze recruitment data.")
58
+ "Recruitment": (lambda frame: initiate_root(self, 'recruitment'), "Analyze recruitment data."),
59
+ "Plaque": (lambda frame: initiate_root(self, 'analyze_plaques'), "Analyze plaque data.")
59
60
  }
60
61
 
61
62
  self.selected_app = tk.StringVar()
@@ -440,6 +440,8 @@ def import_settings(settings_type='mask'):
440
440
  settings = set_default_umap_image_settings(settings={})
441
441
  elif settings_type == 'recruitment':
442
442
  settings = get_analyze_recruitment_default_settings(settings={})
443
+ elif settings_type == 'analyze_plaques':
444
+ settings = {}
443
445
  else:
444
446
  raise ValueError(f"Invalid settings type: {settings_type}")
445
447
 
@@ -493,6 +495,8 @@ def setup_settings_panel(vertical_container, settings_type='mask'):
493
495
  settings = get_perform_regression_default_settings(settings={})
494
496
  elif settings_type == 'recruitment':
495
497
  settings = get_analyze_recruitment_default_settings(settings={})
498
+ elif settings_type == 'analyze_plaques':
499
+ settings = {}
496
500
  else:
497
501
  raise ValueError(f"Invalid settings type: {settings_type}")
498
502
 
@@ -645,7 +649,7 @@ def setup_usage_panel(horizontal_container, btn_col, uppdate_frequency):
645
649
  widgets = [usage_scrollable_frame.scrollable_frame]
646
650
 
647
651
  usage_bars = []
648
- max_elements_per_column = 6
652
+ max_elements_per_column = 5
649
653
  row = 0
650
654
  col = 0
651
655
 
@@ -773,9 +777,9 @@ def start_process(q=None, fig_queue=None, settings_type='mask'):
773
777
  initialize_cuda()
774
778
 
775
779
  process_args = (settings_type, settings, q, fig_queue, stop_requested)
776
- if settings_type in ['mask', 'umap', 'measure', 'simulation', 'sequencing',
777
- 'classify', 'cellpose_dataset', 'train_cellpose', 'ml_analyze', 'cellpose_masks', 'cellpose_all', 'map_barcodes',
778
- 'regression', 'recruitment', 'plaques', 'cellpose_compare', 'vision_scores', 'vision_dataset']:
780
+ if settings_type in ['mask', 'umap', 'measure', 'simulation', 'sequencing', 'classify', 'analyze_plaques',
781
+ 'cellpose_dataset', 'train_cellpose', 'ml_analyze', 'cellpose_masks', 'cellpose_all', 'map_barcodes',
782
+ 'regression', 'recruitment', 'cellpose_compare', 'vision_scores', 'vision_dataset']:
779
783
 
780
784
  # Start the process
781
785
  process = Process(target=run_function_gui, args=process_args)
@@ -486,7 +486,7 @@ def function_gui_wrapper(function=None, settings={}, q=None, fig_queue=None, imp
486
486
  def run_function_gui(settings_type, settings, q, fig_queue, stop_requested):
487
487
 
488
488
  from .gui_utils import process_stdout_stderr
489
- from .core import generate_image_umap, preprocess_generate_masks, generate_ml_scores, identify_masks_finetune, check_cellpose_models, analyze_recruitment, train_cellpose, compare_cellpose_masks, analyze_plaques, generate_dataset, apply_model_to_tar
489
+ from .core import generate_image_umap, preprocess_generate_masks, generate_ml_scores, identify_masks_finetune, check_cellpose_models, analyze_recruitment, train_cellpose, analyze_plaques, compare_cellpose_masks, generate_dataset, apply_model_to_tar
490
490
  from .io import generate_cellpose_train_test
491
491
  from .measure import measure_crop
492
492
  from .sim import run_multiple_simulations
@@ -532,6 +532,9 @@ def run_function_gui(settings_type, settings, q, fig_queue, stop_requested):
532
532
  elif settings_type == 'umap':
533
533
  function = generate_image_umap
534
534
  imports = 1
535
+ elif settings_type == 'analyze_plaques':
536
+ function = analyze_plaques
537
+ imports = 1
535
538
  else:
536
539
  raise ValueError(f"Invalid settings type: {settings_type}")
537
540
  try:
@@ -26,7 +26,7 @@ import atexit
26
26
 
27
27
  from .logger import log_function_call
28
28
 
29
- def _load_images_and_labels(image_files, label_files, circular=False, invert=False, image_extension="*.tif", label_extension="*.tif"):
29
+ def _load_images_and_labels(image_files, label_files, circular=False, invert=False):
30
30
 
31
31
  from .utils import invert_image, apply_mask
32
32
 
@@ -653,7 +653,6 @@ def _rename_and_organize_image_files(src, regex, batch_size=100, pick_slice=Fals
653
653
  from .utils import _extract_filename_metadata, print_progress
654
654
 
655
655
  regular_expression = re.compile(regex)
656
- images_by_key = defaultdict(list)
657
656
  stack_path = os.path.join(src, 'stack')
658
657
  files_processed = 0
659
658
  if not os.path.exists(stack_path) or (os.path.isdir(stack_path) and len(os.listdir(stack_path)) == 0):
@@ -665,7 +664,7 @@ def _rename_and_organize_image_files(src, regex, batch_size=100, pick_slice=Fals
665
664
  start = time.time()
666
665
  batch_filenames = all_filenames[idx:idx+batch_size]
667
666
  for filename in batch_filenames:
668
- images_by_key = _extract_filename_metadata(batch_filenames, src, images_by_key, regular_expression, metadata_type, pick_slice, skip_mode)
667
+ images_by_key = _extract_filename_metadata(batch_filenames, src, regular_expression, metadata_type, pick_slice, skip_mode)
669
668
 
670
669
  if pick_slice:
671
670
  for i, key in enumerate(images_by_key):
@@ -683,16 +682,16 @@ def _rename_and_organize_image_files(src, regex, batch_size=100, pick_slice=Fals
683
682
  files_to_process = len(all_filenames)
684
683
  print_progress(files_processed, files_to_process, n_jobs=1, time_ls=time_ls, batch_size=batch_size, operation_type='Preprocessing filenames')
685
684
 
686
- if os.path.exists(output_path):
687
- print(f'WARNING: A file with the same name already exists at location {output_filename}')
688
- else:
685
+ #if os.path.exists(output_path):
686
+ # print(f'WARNING: A file with the same name already exists at location {output_filename}')
687
+ if not os.path.exists(output_path):
689
688
  mip_image.save(output_path)
690
689
  else:
691
690
  for i, (key, images) in enumerate(images_by_key.items()):
692
- mip = np.max(np.stack(images), axis=0)
693
- mip_image = Image.fromarray(mip)
694
691
  plate, well, field, channel = key[:4]
695
692
  output_dir = os.path.join(src, channel)
693
+ mip = np.max(np.stack(images), axis=0)
694
+ mip_image = Image.fromarray(mip)
696
695
  os.makedirs(output_dir, exist_ok=True)
697
696
  output_filename = f'{plate}_{well}_{field}.tif'
698
697
  output_path = os.path.join(output_dir, output_filename)
@@ -703,9 +702,9 @@ def _rename_and_organize_image_files(src, regex, batch_size=100, pick_slice=Fals
703
702
  files_to_process = len(all_filenames)
704
703
  print_progress(files_processed, files_to_process, n_jobs=1, time_ls=time_ls, batch_size=batch_size, operation_type='Preprocessing filenames')
705
704
 
706
- if os.path.exists(output_path):
707
- print(f'WARNING: A file with the same name already exists at location {output_filename}')
708
- else:
705
+ #if os.path.exists(output_path):
706
+ # print(f'WARNING: A file with the same name already exists at location {output_filename}')
707
+ if not os.path.exists(output_path):
709
708
  mip_image.save(output_path)
710
709
  images_by_key.clear()
711
710
 
@@ -972,8 +971,8 @@ def _mip_all(src, include_first_chan=True):
972
971
  if filename.endswith('.npy'):
973
972
  # Load the array from the file.
974
973
  array = np.load(os.path.join(src, filename))
975
- # Normalize the array using custom parameters (q1=2, q2=98).
976
- array = normalize_to_dtype(array, q1=2, q2=98, percentiles=None)
974
+ # Normalize the array
975
+ #array = normalize_to_dtype(array, q1=0, q2=99, percentiles=None)
977
976
 
978
977
  if array.ndim != 3: # Check if the array is not 3-dimensional.
979
978
  # Log a message indicating a zero array will be generated due to unexpected dimensions.
@@ -1671,6 +1670,7 @@ def preprocess_img_data(settings):
1671
1670
  if plot:
1672
1671
  print(f'plotting {nr} images from {src}/stack')
1673
1672
  plot_arrays(src+'/stack', figuresize, cmap, nr=nr, normalize=normalize)
1673
+
1674
1674
  if all_to_mip:
1675
1675
  _mip_all(src+'/stack')
1676
1676
  if plot:
@@ -998,10 +998,10 @@ def measure_crop(settings):
998
998
  src_fldr = os.path.join(src_fldr, 'merged')
999
999
  print(f"Changed source folder to: {src_fldr}")
1000
1000
 
1001
- if settings['save_measurements']:
1002
- source_folder = os.path.dirname(settings['src'])
1003
- os.makedirs(source_folder+'/measurements', exist_ok=True)
1004
- _create_database(source_folder+'/measurements/measurements.db')
1001
+ #if settings['save_measurements']:
1002
+ #source_folder = os.path.dirname(settings['src'])
1003
+ #os.makedirs(source_folder+'/measurements', exist_ok=True)
1004
+ #_create_database(source_folder+'/measurements/measurements.db')
1005
1005
 
1006
1006
  if settings['cell_mask_dim'] is None:
1007
1007
  settings['include_uninfected'] = True