spacr 0.3.50__tar.gz → 0.3.55__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 (279) hide show
  1. {spacr-0.3.50/spacr.egg-info → spacr-0.3.55}/PKG-INFO +2 -1
  2. {spacr-0.3.50 → spacr-0.3.55}/setup.py +2 -1
  3. {spacr-0.3.50 → spacr-0.3.55}/spacr/gui_elements.py +1 -1
  4. {spacr-0.3.50 → spacr-0.3.55}/spacr/gui_utils.py +4 -116
  5. {spacr-0.3.50 → spacr-0.3.55}/spacr/io.py +114 -140
  6. {spacr-0.3.50 → spacr-0.3.55}/spacr/measure.py +14 -12
  7. {spacr-0.3.50 → spacr-0.3.55}/spacr/ml.py +41 -32
  8. {spacr-0.3.50 → spacr-0.3.55}/spacr/plot.py +167 -307
  9. {spacr-0.3.50 → spacr-0.3.55}/spacr/sequencing.py +13 -9
  10. {spacr-0.3.50 → spacr-0.3.55}/spacr/settings.py +29 -39
  11. {spacr-0.3.50 → spacr-0.3.55}/spacr/submodules.py +19 -19
  12. {spacr-0.3.50 → spacr-0.3.55}/spacr/timelapse.py +16 -16
  13. {spacr-0.3.50 → spacr-0.3.55}/spacr/toxo.py +180 -1
  14. {spacr-0.3.50 → spacr-0.3.55}/spacr/utils.py +95 -164
  15. {spacr-0.3.50 → spacr-0.3.55/spacr.egg-info}/PKG-INFO +2 -1
  16. {spacr-0.3.50 → spacr-0.3.55}/spacr.egg-info/requires.txt +1 -0
  17. {spacr-0.3.50 → spacr-0.3.55}/.readthedocs.yaml +0 -0
  18. {spacr-0.3.50 → spacr-0.3.55}/LICENSE +0 -0
  19. {spacr-0.3.50 → spacr-0.3.55}/MANIFEST.in +0 -0
  20. {spacr-0.3.50 → spacr-0.3.55}/README.rst +0 -0
  21. {spacr-0.3.50 → spacr-0.3.55}/deploy_docs.sh +0 -0
  22. {spacr-0.3.50 → spacr-0.3.55}/docs/requirements.txt +0 -0
  23. {spacr-0.3.50 → spacr-0.3.55}/docs/source/Makefile +0 -0
  24. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/doctrees/environment.pickle +0 -0
  25. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_modules/index.html +0 -0
  26. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_modules/spacr/app_annotate.html +0 -0
  27. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_modules/spacr/app_classify.html +0 -0
  28. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_modules/spacr/app_make_masks.html +0 -0
  29. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_modules/spacr/app_mask.html +0 -0
  30. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_modules/spacr/app_measure.html +0 -0
  31. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_modules/spacr/app_sequencing.html +0 -0
  32. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_modules/spacr/app_umap.html +0 -0
  33. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_modules/spacr/core.html +0 -0
  34. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_modules/spacr/deep_spacr.html +0 -0
  35. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_modules/spacr/graph_learning.html +0 -0
  36. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_modules/spacr/gui.html +0 -0
  37. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_modules/spacr/gui_core.html +0 -0
  38. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_modules/spacr/gui_elements.html +0 -0
  39. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_modules/spacr/gui_utils.html +0 -0
  40. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_modules/spacr/io.html +0 -0
  41. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_modules/spacr/logger.html +0 -0
  42. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_modules/spacr/measure.html +0 -0
  43. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_modules/spacr/plot.html +0 -0
  44. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_modules/spacr/sequencing.html +0 -0
  45. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_modules/spacr/settings.html +0 -0
  46. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_modules/spacr/sim.html +0 -0
  47. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_modules/spacr/timelapse.html +0 -0
  48. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_modules/spacr/utils.html +0 -0
  49. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_sources/index.rst.txt +0 -0
  50. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_sources/modules.rst.txt +0 -0
  51. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_sources/spacr.rst.txt +0 -0
  52. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_static/_sphinx_javascript_frameworks_compat.js +0 -0
  53. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_static/basic.css +0 -0
  54. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_static/css/badge_only.css +0 -0
  55. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_static/css/fonts/Roboto-Slab-Bold.woff +0 -0
  56. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_static/css/fonts/Roboto-Slab-Bold.woff2 +0 -0
  57. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_static/css/fonts/Roboto-Slab-Regular.woff +0 -0
  58. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_static/css/fonts/Roboto-Slab-Regular.woff2 +0 -0
  59. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_static/css/fonts/fontawesome-webfont.eot +0 -0
  60. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_static/css/fonts/fontawesome-webfont.svg +0 -0
  61. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_static/css/fonts/fontawesome-webfont.ttf +0 -0
  62. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_static/css/fonts/fontawesome-webfont.woff +0 -0
  63. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_static/css/fonts/fontawesome-webfont.woff2 +0 -0
  64. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_static/css/fonts/lato-bold-italic.woff +0 -0
  65. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_static/css/fonts/lato-bold-italic.woff2 +0 -0
  66. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_static/css/fonts/lato-bold.woff +0 -0
  67. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_static/css/fonts/lato-bold.woff2 +0 -0
  68. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_static/css/fonts/lato-normal-italic.woff +0 -0
  69. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_static/css/fonts/lato-normal-italic.woff2 +0 -0
  70. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_static/css/fonts/lato-normal.woff +0 -0
  71. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_static/css/fonts/lato-normal.woff2 +0 -0
  72. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_static/css/theme.css +0 -0
  73. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_static/doctools.js +0 -0
  74. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_static/documentation_options.js +0 -0
  75. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_static/file.png +0 -0
  76. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_static/jquery.js +0 -0
  77. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_static/js/badge_only.js +0 -0
  78. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_static/js/html5shiv-printshiv.min.js +0 -0
  79. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_static/js/html5shiv.min.js +0 -0
  80. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_static/js/theme.js +0 -0
  81. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_static/language_data.js +0 -0
  82. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_static/minus.png +0 -0
  83. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_static/plus.png +0 -0
  84. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_static/pygments.css +0 -0
  85. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_static/searchtools.js +0 -0
  86. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/_static/sphinx_highlight.js +0 -0
  87. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/genindex.html +0 -0
  88. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/index.html +0 -0
  89. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/modules.html +0 -0
  90. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/objects.inv +0 -0
  91. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/py-modindex.html +0 -0
  92. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/search.html +0 -0
  93. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/searchindex.js +0 -0
  94. {spacr-0.3.50 → spacr-0.3.55}/docs/source/_build/html/spacr.html +0 -0
  95. {spacr-0.3.50 → spacr-0.3.55}/docs/source/conf.py +0 -0
  96. {spacr-0.3.50 → spacr-0.3.55}/docs/source/index.rst +0 -0
  97. {spacr-0.3.50 → spacr-0.3.55}/docs/source/make.bat +0 -0
  98. {spacr-0.3.50 → spacr-0.3.55}/docs/source/modules.rst +0 -0
  99. {spacr-0.3.50 → spacr-0.3.55}/docs/source/spacr.rst +0 -0
  100. {spacr-0.3.50 → spacr-0.3.55}/environment.yaml +0 -0
  101. {spacr-0.3.50 → spacr-0.3.55}/fonts/OpenSans-Regular.ttf +0 -0
  102. {spacr-0.3.50 → spacr-0.3.55}/notebooks/cv_scoring_nb.ipynb +0 -0
  103. {spacr-0.3.50 → spacr-0.3.55}/notebooks/deep_learning_spacr.ipynb +0 -0
  104. {spacr-0.3.50 → spacr-0.3.55}/notebooks/machine_learning_spacr_nb.ipynb +0 -0
  105. {spacr-0.3.50 → spacr-0.3.55}/notebooks/spacr_0.1_all_settings_git.ipynb +0 -0
  106. {spacr-0.3.50 → spacr-0.3.55}/notebooks/spacr_0.1_minimal.ipynb +0 -0
  107. {spacr-0.3.50 → spacr-0.3.55}/path/home/carruthers/datasets/plate1/measurements/measurements.db +0 -0
  108. {spacr-0.3.50 → spacr-0.3.55}/path/home/carruthers/datasets/plate1/settings/measure_crop_settings.csv +0 -0
  109. {spacr-0.3.50 → spacr-0.3.55}/path/settings/preprocess_generate_masks_settings.csv +0 -0
  110. {spacr-0.3.50 → spacr-0.3.55}/requirements.txt +0 -0
  111. {spacr-0.3.50 → spacr-0.3.55}/settings/measure_crop_settings.csv +0 -0
  112. {spacr-0.3.50 → spacr-0.3.55}/setup.cfg +0 -0
  113. {spacr-0.3.50 → spacr-0.3.55}/setup_docs.sh +0 -0
  114. {spacr-0.3.50 → spacr-0.3.55}/source/conf.py +0 -0
  115. {spacr-0.3.50 → spacr-0.3.55}/source/index.rst +0 -0
  116. {spacr-0.3.50 → spacr-0.3.55}/source/modules.rst +0 -0
  117. {spacr-0.3.50 → spacr-0.3.55}/source/setup.rst +0 -0
  118. {spacr-0.3.50 → spacr-0.3.55}/source/spacr.rst +0 -0
  119. {spacr-0.3.50 → spacr-0.3.55}/spacr/__init__.py +0 -0
  120. {spacr-0.3.50 → spacr-0.3.55}/spacr/__main__.py +0 -0
  121. {spacr-0.3.50 → spacr-0.3.55}/spacr/app_annotate.py +0 -0
  122. {spacr-0.3.50 → spacr-0.3.55}/spacr/app_classify.py +0 -0
  123. {spacr-0.3.50 → spacr-0.3.55}/spacr/app_make_masks.py +0 -0
  124. {spacr-0.3.50 → spacr-0.3.55}/spacr/app_mask.py +0 -0
  125. {spacr-0.3.50 → spacr-0.3.55}/spacr/app_measure.py +0 -0
  126. {spacr-0.3.50 → spacr-0.3.55}/spacr/app_sequencing.py +0 -0
  127. {spacr-0.3.50 → spacr-0.3.55}/spacr/app_umap.py +0 -0
  128. {spacr-0.3.50 → spacr-0.3.55}/spacr/cellpose.py +0 -0
  129. {spacr-0.3.50 → spacr-0.3.55}/spacr/chat_bot.py +0 -0
  130. {spacr-0.3.50 → spacr-0.3.55}/spacr/core.py +0 -0
  131. {spacr-0.3.50 → spacr-0.3.55}/spacr/deep_spacr.py +0 -0
  132. {spacr-0.3.50 → spacr-0.3.55}/spacr/gui.py +0 -0
  133. {spacr-0.3.50 → spacr-0.3.55}/spacr/gui_core.py +0 -0
  134. {spacr-0.3.50 → spacr-0.3.55}/spacr/logger.py +0 -0
  135. {spacr-0.3.50 → spacr-0.3.55}/spacr/mediar.py +0 -0
  136. {spacr-0.3.50 → spacr-0.3.55}/spacr/openai.py +0 -0
  137. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/.gitignore +0 -0
  138. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/LICENSE +0 -0
  139. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/README.md +0 -0
  140. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/SetupDict.py +0 -0
  141. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/config/baseline.json +0 -0
  142. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/config/mediar_example.json +0 -0
  143. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/config/pred/pred_mediar.json +0 -0
  144. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/config/step1_pretraining/phase1.json +0 -0
  145. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/config/step1_pretraining/phase2.json +0 -0
  146. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/config/step2_finetuning/finetuning1.json +0 -0
  147. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/config/step2_finetuning/finetuning2.json +0 -0
  148. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/config/step3_prediction/base_prediction.json +0 -0
  149. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/config/step3_prediction/ensemble_tta.json +0 -0
  150. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/core/BasePredictor.py +0 -0
  151. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/core/BaseTrainer.py +0 -0
  152. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/core/Baseline/Predictor.py +0 -0
  153. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/core/Baseline/Trainer.py +0 -0
  154. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/core/Baseline/__init__.py +0 -0
  155. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/core/Baseline/utils.py +0 -0
  156. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/core/MEDIAR/EnsemblePredictor.py +0 -0
  157. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/core/MEDIAR/Predictor.py +0 -0
  158. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/core/MEDIAR/Trainer.py +0 -0
  159. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/core/MEDIAR/__init__.py +0 -0
  160. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/core/MEDIAR/utils.py +0 -0
  161. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/core/__init__.py +0 -0
  162. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/core/utils.py +0 -0
  163. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/evaluate.py +0 -0
  164. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/generate_mapping.py +0 -0
  165. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/image/examples/img1.tiff +0 -0
  166. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/image/examples/img2.tif +0 -0
  167. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/image/failure_cases.png +0 -0
  168. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/image/mediar_framework.png +0 -0
  169. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/image/mediar_model.PNG +0 -0
  170. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/image/mediar_results.png +0 -0
  171. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/main.py +0 -0
  172. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/predict.py +0 -0
  173. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/requirements.txt +0 -0
  174. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/train_tools/__init__.py +0 -0
  175. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/train_tools/data_utils/__init__.py +0 -0
  176. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/train_tools/data_utils/custom/CellAware.py +0 -0
  177. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/train_tools/data_utils/custom/LoadImage.py +0 -0
  178. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/train_tools/data_utils/custom/NormalizeImage.py +0 -0
  179. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/train_tools/data_utils/custom/__init__.py +0 -0
  180. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/train_tools/data_utils/custom/modalities.pkl +0 -0
  181. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/train_tools/data_utils/datasetter.py +0 -0
  182. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/train_tools/data_utils/transforms.py +0 -0
  183. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/train_tools/data_utils/utils.py +0 -0
  184. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/train_tools/measures.py +0 -0
  185. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/train_tools/models/MEDIARFormer.py +0 -0
  186. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/train_tools/models/__init__.py +0 -0
  187. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/MEDIAR/train_tools/utils.py +0 -0
  188. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/data/lopit.csv +0 -0
  189. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/data/toxoplasma_metadata.csv +0 -0
  190. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/OFL.txt +0 -0
  191. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/OpenSans-Italic-VariableFont_wdth,wght.ttf +0 -0
  192. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/OpenSans-VariableFont_wdth,wght.ttf +0 -0
  193. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/README.txt +0 -0
  194. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/static/OpenSans-Bold.ttf +0 -0
  195. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/static/OpenSans-BoldItalic.ttf +0 -0
  196. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/static/OpenSans-ExtraBold.ttf +0 -0
  197. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/static/OpenSans-ExtraBoldItalic.ttf +0 -0
  198. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/static/OpenSans-Italic.ttf +0 -0
  199. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/static/OpenSans-Light.ttf +0 -0
  200. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/static/OpenSans-LightItalic.ttf +0 -0
  201. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/static/OpenSans-Medium.ttf +0 -0
  202. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/static/OpenSans-MediumItalic.ttf +0 -0
  203. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/static/OpenSans-Regular.ttf +0 -0
  204. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/static/OpenSans-SemiBold.ttf +0 -0
  205. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/static/OpenSans-SemiBoldItalic.ttf +0 -0
  206. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/static/OpenSans_Condensed-Bold.ttf +0 -0
  207. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/static/OpenSans_Condensed-BoldItalic.ttf +0 -0
  208. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/static/OpenSans_Condensed-ExtraBold.ttf +0 -0
  209. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/static/OpenSans_Condensed-ExtraBoldItalic.ttf +0 -0
  210. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/static/OpenSans_Condensed-Italic.ttf +0 -0
  211. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/static/OpenSans_Condensed-Light.ttf +0 -0
  212. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/static/OpenSans_Condensed-LightItalic.ttf +0 -0
  213. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/static/OpenSans_Condensed-Medium.ttf +0 -0
  214. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/static/OpenSans_Condensed-MediumItalic.ttf +0 -0
  215. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/static/OpenSans_Condensed-Regular.ttf +0 -0
  216. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/static/OpenSans_Condensed-SemiBold.ttf +0 -0
  217. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/static/OpenSans_Condensed-SemiBoldItalic.ttf +0 -0
  218. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-Bold.ttf +0 -0
  219. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-BoldItalic.ttf +0 -0
  220. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-ExtraBold.ttf +0 -0
  221. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-ExtraBoldItalic.ttf +0 -0
  222. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-Italic.ttf +0 -0
  223. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-Light.ttf +0 -0
  224. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-LightItalic.ttf +0 -0
  225. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-Medium.ttf +0 -0
  226. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-MediumItalic.ttf +0 -0
  227. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-Regular.ttf +0 -0
  228. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-SemiBold.ttf +0 -0
  229. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-SemiBoldItalic.ttf +0 -0
  230. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/icons/abort.png +0 -0
  231. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/icons/annotate.png +0 -0
  232. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/icons/cellpose_all.png +0 -0
  233. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/icons/cellpose_masks.png +0 -0
  234. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/icons/classify.png +0 -0
  235. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/icons/convert.png +0 -0
  236. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/icons/default.png +0 -0
  237. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/icons/dna_matrix.mp4 +0 -0
  238. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/icons/download.png +0 -0
  239. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/icons/logo.pdf +0 -0
  240. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/icons/logo_spacr.png +0 -0
  241. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/icons/logo_spacr_1.png +0 -0
  242. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/icons/make_masks.png +0 -0
  243. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/icons/map_barcodes.png +0 -0
  244. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/icons/mask.png +0 -0
  245. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/icons/measure.png +0 -0
  246. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/icons/ml_analyze.png +0 -0
  247. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/icons/plaque.png +0 -0
  248. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/icons/recruitment.png +0 -0
  249. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/icons/regression.png +0 -0
  250. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/icons/run.png +0 -0
  251. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/icons/sequencing.png +0 -0
  252. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/icons/settings.png +0 -0
  253. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/icons/train_cellpose.png +0 -0
  254. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/icons/umap.png +0 -0
  255. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/images/plate1_E01_T0001F001L01A01Z01C02.tif +0 -0
  256. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/images/plate1_E01_T0001F001L01A02Z01C01.tif +0 -0
  257. {spacr-0.3.50 → spacr-0.3.55}/spacr/resources/images/plate1_E01_T0001F001L01A03Z01C03.tif +0 -0
  258. {spacr-0.3.50 → spacr-0.3.55}/spacr/sim.py +0 -0
  259. {spacr-0.3.50 → spacr-0.3.55}/spacr/version.py +0 -0
  260. {spacr-0.3.50 → spacr-0.3.55}/spacr.egg-info/SOURCES.txt +0 -0
  261. {spacr-0.3.50 → spacr-0.3.55}/spacr.egg-info/dependency_links.txt +0 -0
  262. {spacr-0.3.50 → spacr-0.3.55}/spacr.egg-info/entry_points.txt +0 -0
  263. {spacr-0.3.50 → spacr-0.3.55}/spacr.egg-info/top_level.txt +0 -0
  264. {spacr-0.3.50 → spacr-0.3.55}/tests/test_annotate_app.py +0 -0
  265. {spacr-0.3.50 → spacr-0.3.55}/tests/test_core.py +0 -0
  266. {spacr-0.3.50 → spacr-0.3.55}/tests/test_gui_classify_app.py +0 -0
  267. {spacr-0.3.50 → spacr-0.3.55}/tests/test_gui_mask_app.py +0 -0
  268. {spacr-0.3.50 → spacr-0.3.55}/tests/test_gui_measure_app.py +0 -0
  269. {spacr-0.3.50 → spacr-0.3.55}/tests/test_gui_sim_app.py +0 -0
  270. {spacr-0.3.50 → spacr-0.3.55}/tests/test_gui_utils.py +0 -0
  271. {spacr-0.3.50 → spacr-0.3.55}/tests/test_io.py +0 -0
  272. {spacr-0.3.50 → spacr-0.3.55}/tests/test_mask_app.py +0 -0
  273. {spacr-0.3.50 → spacr-0.3.55}/tests/test_measure.py +0 -0
  274. {spacr-0.3.50 → spacr-0.3.55}/tests/test_plot.py +0 -0
  275. {spacr-0.3.50 → spacr-0.3.55}/tests/test_sim.py +0 -0
  276. {spacr-0.3.50 → spacr-0.3.55}/tests/test_timelapse.py +0 -0
  277. {spacr-0.3.50 → spacr-0.3.55}/tests/test_train.py +0 -0
  278. {spacr-0.3.50 → spacr-0.3.55}/tests/test_umap.py +0 -0
  279. {spacr-0.3.50 → spacr-0.3.55}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: spacr
3
- Version: 0.3.50
3
+ Version: 0.3.55
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
@@ -16,6 +16,7 @@ Requires-Dist: scipy<2.0,>=1.12.0
16
16
  Requires-Dist: cellpose<4.0,>=3.0.6
17
17
  Requires-Dist: scikit-image<1.0,>=0.22.0
18
18
  Requires-Dist: scikit-learn<2.0,>=1.4.1
19
+ Requires-Dist: scikit-posthocs<0.20,>=0.10.0
19
20
  Requires-Dist: mahotas<2.0,>=1.4.13
20
21
  Requires-Dist: btrack<1.0,>=0.6.5
21
22
  Requires-Dist: trackpy<1.0,>=0.6.2
@@ -12,6 +12,7 @@ dependencies = [
12
12
  'cellpose>=3.0.6,<4.0',
13
13
  'scikit-image>=0.22.0,<1.0',
14
14
  'scikit-learn>=1.4.1,<2.0',
15
+ 'scikit-posthocs>=0.10.0, <0.20',
15
16
  'mahotas>=1.4.13,<2.0',
16
17
  'btrack>=0.6.5,<1.0',
17
18
  'trackpy>=0.6.2,<1.0',
@@ -68,7 +69,7 @@ dependencies = [
68
69
 
69
70
  setup(
70
71
  name="spacr",
71
- version="0.3.50",
72
+ version="0.3.55",
72
73
  author="Einar Birnir Olafsson",
73
74
  author_email="olafsson@med.umich.com",
74
75
  description="Spatial phenotype analysis of crisp screens (SpaCr)",
@@ -706,7 +706,7 @@ class spacrProgressBar(ttk.Progressbar):
706
706
 
707
707
  def set_label_position(self):
708
708
  if self.label and self.progress_label:
709
- row_info = self.grid_info().get('row', 0)
709
+ row_info = self.grid_info().get('row_name', 0)
710
710
  col_info = self.grid_info().get('column', 0)
711
711
  col_span = self.grid_info().get('columnspan', 1)
712
712
  self.progress_label.grid(row=row_info + 1, column=col_info, columnspan=col_span, pady=5, padx=5, sticky='ew')
@@ -76,37 +76,7 @@ def load_app(root, app_name, app_func):
76
76
  root.current_app_exit_func()
77
77
  else:
78
78
  proceed_with_app(root, app_name, app_func)
79
-
80
- def parse_list_v1(value):
81
- """
82
- Parses a string representation of a list and returns the parsed list.
83
-
84
- Args:
85
- value (str): The string representation of the list.
86
-
87
- Returns:
88
- list: The parsed list.
89
79
 
90
- Raises:
91
- ValueError: If the input value is not a valid list format or contains mixed types or unsupported types.
92
- """
93
- try:
94
- parsed_value = ast.literal_eval(value)
95
- if isinstance(parsed_value, list):
96
- # Check if the list elements are homogeneous (all int or all str)
97
- if all(isinstance(item, int) for item in parsed_value):
98
- return parsed_value
99
- elif all(isinstance(item, str) for item in parsed_value):
100
- return parsed_value
101
- elif all(isinstance(item, float) for item in parsed_value):
102
- return parsed_value
103
- else:
104
- raise ValueError("List contains mixed types or unsupported types")
105
- else:
106
- raise ValueError(f"Expected a list but got {type(parsed_value).__name__}")
107
- except (ValueError, SyntaxError) as e:
108
- raise ValueError(f"Invalid format for list: {value}. Error: {e}")
109
-
110
80
  def parse_list(value):
111
81
  """
112
82
  Parses a string representation of a list and returns the parsed list.
@@ -128,6 +98,9 @@ def parse_list(value):
128
98
  return parsed_value
129
99
  else:
130
100
  raise ValueError("List contains mixed types or unsupported types")
101
+ elif isinstance(parsed_value, tuple):
102
+ # Convert tuple to list if it’s a single-element tuple
103
+ return list(parsed_value) if len(parsed_value) > 1 else [parsed_value[0]]
131
104
  else:
132
105
  raise ValueError(f"Expected a list but got {type(parsed_value).__name__}")
133
106
  except (ValueError, SyntaxError) as e:
@@ -391,7 +364,7 @@ def convert_settings_dict_for_gui(settings):
391
364
  'nucleus_chann_dim': ('combo', chans, None),
392
365
  'pathogen_mask_dim': ('combo', chans, None),
393
366
  'pathogen_chann_dim': ('combo', chans, None),
394
- 'crop_mode': ('combo', ['cell', 'nucleus', 'pathogen', '[cell, nucleus, pathogen]', '[cell,nucleus, pathogen]'], ['cell']),
367
+ 'crop_mode': ('combo', [['cell'], ['nucleus'], ['pathogen'], ['cell', 'nucleus'], ['cell', 'pathogen'], ['nucleus', 'pathogen'], ['cell', 'nucleus', 'pathogen']], ['cell']),
395
368
  'magnification': ('combo', [20, 40, 60], 20),
396
369
  'nucleus_channel': ('combo', chans_v2, None),
397
370
  'cell_channel': ('combo', chans_v2, None),
@@ -697,91 +670,6 @@ def ensure_after_tasks(frame):
697
670
  if not hasattr(frame, 'after_tasks'):
698
671
  frame.after_tasks = []
699
672
 
700
- def display_gif_in_plot_frame_v1(gif_path, parent_frame):
701
- """Display and zoom a GIF to fill the entire parent_frame, maintaining aspect ratio, with lazy resizing and caching."""
702
- # Clear parent_frame if it contains any previous widgets
703
- for widget in parent_frame.winfo_children():
704
- widget.destroy()
705
-
706
- # Load the GIF
707
- gif = Image.open(gif_path)
708
-
709
- # Get the aspect ratio of the GIF
710
- gif_width, gif_height = gif.size
711
- gif_aspect_ratio = gif_width / gif_height
712
-
713
- # Create a label to display the GIF and configure it to fill the parent_frame
714
- label = tk.Label(parent_frame, bg="black")
715
- label.grid(row=0, column=0, sticky="nsew") # Expands in all directions (north, south, east, west)
716
-
717
- # Configure parent_frame to stretch the label to fill available space
718
- parent_frame.grid_rowconfigure(0, weight=1)
719
- parent_frame.grid_columnconfigure(0, weight=1)
720
-
721
- # Cache for storing resized frames (lazily filled)
722
- resized_frames_cache = {}
723
-
724
- # Last frame dimensions
725
- last_frame_width = 0
726
- last_frame_height = 0
727
-
728
- def resize_and_crop_frame(frame_idx, frame_width, frame_height):
729
- """Resize and crop the current frame of the GIF to fit the parent_frame while maintaining the aspect ratio."""
730
- # If the frame is already cached at the current size, return it
731
- if (frame_idx, frame_width, frame_height) in resized_frames_cache:
732
- return resized_frames_cache[(frame_idx, frame_width, frame_height)]
733
-
734
- # Calculate the scaling factor to zoom in on the GIF
735
- scale_factor = max(frame_width / gif_width, frame_height / gif_height)
736
-
737
- # Calculate new dimensions while maintaining the aspect ratio
738
- new_width = int(gif_width * scale_factor)
739
- new_height = int(gif_height * scale_factor)
740
-
741
- # Resize the GIF to fit the frame
742
- gif.seek(frame_idx)
743
- resized_gif = gif.copy().resize((new_width, new_height), Image.Resampling.LANCZOS)
744
-
745
- # Calculate the cropping box to center the resized GIF in the frame
746
- crop_left = (new_width - frame_width) // 2
747
- crop_top = (new_height - frame_height) // 2
748
- crop_right = crop_left + frame_width
749
- crop_bottom = crop_top + frame_height
750
-
751
- # Crop the resized GIF to exactly fit the frame
752
- cropped_gif = resized_gif.crop((crop_left, crop_top, crop_right, crop_bottom))
753
-
754
- # Convert the cropped frame to a Tkinter-compatible format
755
- frame_image = ImageTk.PhotoImage(cropped_gif)
756
-
757
- # Cache the resized frame
758
- resized_frames_cache[(frame_idx, frame_width, frame_height)] = frame_image
759
-
760
- return frame_image
761
-
762
- def update_frame(frame_idx):
763
- """Update the GIF frame using lazy resizing and caching."""
764
- # Get the current size of the parent_frame
765
- frame_width = parent_frame.winfo_width()
766
- frame_height = parent_frame.winfo_height()
767
-
768
- # Only resize if the frame size has changed
769
- nonlocal last_frame_width, last_frame_height
770
- if frame_width != last_frame_width or frame_height != last_frame_height:
771
- last_frame_width, last_frame_height = frame_width, frame_height
772
-
773
- # Get the resized and cropped frame image
774
- frame_image = resize_and_crop_frame(frame_idx, frame_width, frame_height)
775
- label.config(image=frame_image)
776
- label.image = frame_image # Keep a reference to avoid garbage collection
777
-
778
- # Move to the next frame, or loop back to the beginning
779
- next_frame_idx = (frame_idx + 1) % gif.n_frames
780
- parent_frame.after(gif.info['duration'], update_frame, next_frame_idx)
781
-
782
- # Start the GIF animation from frame 0
783
- update_frame(0)
784
-
785
673
  def display_gif_in_plot_frame(gif_path, parent_frame):
786
674
  """Display and zoom a GIF to fill the entire parent_frame, maintaining aspect ratio, with lazy resizing and caching."""
787
675
  # Clear parent_frame if it contains any previous widgets
@@ -292,121 +292,6 @@ def _load_normalized_images_and_labels(image_files, label_files, channels=None,
292
292
 
293
293
  return normalized_images, labels, image_names, label_names, orig_dims
294
294
 
295
- def _load_normalized_images_and_labels_v1(image_files, label_files, channels=None, percentiles=None, invert=False, visualize=False, remove_background=False, background=0, Signal_to_noise=10, target_height=None, target_width=None):
296
-
297
- from .plot import normalize_and_visualize, plot_resize
298
- from .utils import invert_image, apply_mask
299
- from skimage.transform import resize as resizescikit
300
-
301
- if isinstance(percentiles, list):
302
- if len(percentiles) !=2:
303
- percentiles = None
304
- if not percentiles[0] is int:
305
- percentiles = None
306
- if not percentiles[1] is int:
307
- percentiles = None
308
-
309
- signal_thresholds = background * Signal_to_noise
310
- lower_percentile = 2
311
-
312
- images = []
313
- labels = []
314
- orig_dims = []
315
-
316
- num_channels = 4
317
- percentiles_1 = [[] for _ in range(num_channels)]
318
- percentiles_99 = [[] for _ in range(num_channels)]
319
-
320
- image_names = [os.path.basename(f) for f in image_files]
321
- image_dir = os.path.dirname(image_files[0])
322
-
323
- if label_files is not None:
324
- label_names = [os.path.basename(f) for f in label_files]
325
- label_dir = os.path.dirname(label_files[0])
326
-
327
- # Load, normalize, and resize images
328
- for i, img_file in enumerate(image_files):
329
- image = cellpose.io.imread(img_file)
330
- orig_dims.append((image.shape[0], image.shape[1]))
331
- if invert:
332
- image = invert_image(image)
333
-
334
- # If specific channels are specified, select them
335
- if channels is not None and image.ndim == 3:
336
- image = image[..., channels]
337
-
338
- if remove_background:
339
- image[image < background] = 0
340
-
341
- if image.ndim < 3:
342
- image = np.expand_dims(image, axis=-1)
343
-
344
- if percentiles is None:
345
- for c in range(image.shape[-1]):
346
- p1 = np.percentile(image[..., c], lower_percentile)
347
- percentiles_1[c].append(p1)
348
- for percentile in [98, 99, 99.9, 99.99, 99.999]:
349
- p = np.percentile(image[..., c], percentile)
350
- if p > signal_thresholds:
351
- percentiles_99[c].append(p)
352
- break
353
-
354
- # Resize image
355
- if target_height is not None and target_width is not None:
356
- if image.ndim == 2:
357
- image_shape = (target_height, target_width)
358
- elif image.ndim == 3:
359
- image_shape = (target_height, target_width, image.shape[-1])
360
-
361
- image = resizescikit(image, image_shape, preserve_range=True, anti_aliasing=True).astype(image.dtype)
362
-
363
- images.append(image)
364
-
365
- if percentiles is None:
366
- # Calculate average percentiles for normalization
367
- avg_p1 = [np.mean(p) for p in percentiles_1]
368
- avg_p99 = [np.mean(p) if len(p) > 0 else np.mean(percentiles_1[i]) for i, p in enumerate(percentiles_99)]
369
-
370
- print(f'Average 1st percentiles: {avg_p1}, Average 99th percentiles: {avg_p99}')
371
-
372
- normalized_images = []
373
- for image in images:
374
- normalized_image = np.zeros_like(image, dtype=np.float32)
375
- for c in range(image.shape[-1]):
376
- normalized_image[..., c] = rescale_intensity(image[..., c], in_range=(avg_p1[c], avg_p99[c]), out_range=(0, 1))
377
- normalized_images.append(normalized_image)
378
- if visualize:
379
- normalize_and_visualize(image, normalized_image, title=f"Channel {c+1} Normalized")
380
- else:
381
- normalized_images = []
382
- for image in images:
383
- normalized_image = np.zeros_like(image, dtype=np.float32)
384
- for c in range(image.shape[-1]):
385
- low_p = np.percentile(image[..., c], percentiles[0])
386
- high_p = np.percentile(image[..., c], percentiles[1])
387
- normalized_image[..., c] = rescale_intensity(image[..., c], in_range=(low_p, high_p), out_range=(0, 1))
388
- normalized_images.append(normalized_image)
389
- if visualize:
390
- normalize_and_visualize(image, normalized_image, title=f"Channel {c+1} Normalized")
391
-
392
- if label_files is not None:
393
- for lbl_file in label_files:
394
- label = cellpose.io.imread(lbl_file)
395
- # Resize label
396
- if target_height is not None and target_width is not None:
397
- label = resizescikit(label, (target_height, target_width), order=0, preserve_range=True, anti_aliasing=False).astype(label.dtype)
398
- labels.append(label)
399
- else:
400
- label_names = []
401
- label_dir = None
402
-
403
- print(f'Loaded and normalized {len(normalized_images)} images and {len(labels)} labels from {image_dir} and {label_dir}')
404
-
405
- if visualize and images and labels:
406
- plot_resize(images, normalized_images, labels, labels)
407
-
408
- return normalized_images, labels, image_names, label_names, orig_dims
409
-
410
295
  class CombineLoaders:
411
296
 
412
297
  """
@@ -1875,6 +1760,9 @@ def _read_and_join_tables(db_path, table_names=['cell', 'cytoplasm', 'nucleus',
1875
1760
  Returns:
1876
1761
  pandas.DataFrame: The joined DataFrame containing the data from the specified tables, or None if an error occurs.
1877
1762
  """
1763
+ from .utils import rename_columns_in_db
1764
+ rename_columns_in_db(db_path)
1765
+
1878
1766
  conn = sqlite3.connect(db_path)
1879
1767
  dataframes = {}
1880
1768
  for table_name in table_names:
@@ -1885,11 +1773,11 @@ def _read_and_join_tables(db_path, table_names=['cell', 'cytoplasm', 'nucleus',
1885
1773
  print(e)
1886
1774
  conn.close()
1887
1775
  if 'png_list' in dataframes:
1888
- png_list_df = dataframes['png_list'][['cell_id', 'png_path', 'plate', 'row', 'col']].copy()
1776
+ png_list_df = dataframes['png_list'][['cell_id', 'png_path', 'plate', 'row_name', 'column_name']].copy()
1889
1777
  png_list_df['cell_id'] = png_list_df['cell_id'].str[1:].astype(int)
1890
1778
  png_list_df.rename(columns={'cell_id': 'object_label'}, inplace=True)
1891
1779
  if 'cell' in dataframes:
1892
- join_cols = ['object_label', 'plate', 'row', 'col']
1780
+ join_cols = ['object_label', 'plate', 'row_name', 'column_name']
1893
1781
  dataframes['cell'] = pd.merge(dataframes['cell'], png_list_df, on=join_cols, how='left')
1894
1782
  else:
1895
1783
  print("Cell table not found in database tables.")
@@ -2190,6 +2078,8 @@ def _read_db(db_loc, tables):
2190
2078
  Returns:
2191
2079
  - dfs (list): A list of pandas DataFrames, each containing the data from a table.
2192
2080
  """
2081
+ from .utils import rename_columns_in_db
2082
+ rename_columns_in_db(db_loc)
2193
2083
  conn = sqlite3.connect(db_loc)
2194
2084
  dfs = []
2195
2085
  for table in tables:
@@ -2310,7 +2200,7 @@ def _read_and_merge_data(locs, tables, verbose=False, nuclei_limit=False, pathog
2310
2200
  merged_df = merged_df.merge(pathogens_g_df, left_index=True, right_index=True)
2311
2201
 
2312
2202
  #Add prc column (plate row column)
2313
- metadata = metadata.assign(prc = lambda x: x['plate'] + '_' + x['row'] + '_' +x['col'])
2203
+ metadata = metadata.assign(prc = lambda x: x['plate'] + '_' + x['row_name'] + '_' +x['column_name'])
2314
2204
 
2315
2205
  #Count cells per well
2316
2206
  cells_well = pd.DataFrame(metadata.groupby('prc')['object_label'].nunique())
@@ -2322,7 +2212,7 @@ def _read_and_merge_data(locs, tables, verbose=False, nuclei_limit=False, pathog
2322
2212
  metadata.drop(columns=object_label_cols, inplace=True)
2323
2213
 
2324
2214
  #Add prcfo column (plate row column field object)
2325
- metadata = metadata.assign(prcfo = lambda x: x['plate'] + '_' + x['row'] + '_' +x['col']+ '_' +x['field']+ '_' +x['object_label'])
2215
+ metadata = metadata.assign(prcfo = lambda x: x['plate'] + '_' + x['row_name'] + '_' +x['column_name']+ '_' +x['field']+ '_' +x['object_label'])
2326
2216
  metadata.set_index('prcfo', inplace=True)
2327
2217
 
2328
2218
  merged_df = metadata.merge(merged_df, left_index=True, right_index=True)
@@ -2517,6 +2407,10 @@ def _copy_missclassified(df):
2517
2407
  return
2518
2408
 
2519
2409
  def _read_db(db_loc, tables):
2410
+
2411
+ from .utils import rename_columns_in_db
2412
+
2413
+ rename_columns_in_db(db_loc)
2520
2414
  conn = sqlite3.connect(db_loc) # Create a connection to the database
2521
2415
  dfs = []
2522
2416
  for table in tables:
@@ -2667,7 +2561,7 @@ def _read_and_merge_data(locs, tables, verbose=False, nuclei_limit=False, pathog
2667
2561
  merged_df = merged_df.merge(pathogens_g_df, left_index=True, right_index=True)
2668
2562
 
2669
2563
  #Add prc column (plate row column)
2670
- metadata = metadata.assign(prc = lambda x: x['plate'] + '_' + x['row'] + '_' +x['col'])
2564
+ metadata = metadata.assign(prc = lambda x: x['plate'] + '_' + x['row_name'] + '_' +x['column_name'])
2671
2565
 
2672
2566
  #Count cells per well
2673
2567
  cells_well = pd.DataFrame(metadata.groupby('prc')['object_label'].nunique())
@@ -2679,7 +2573,7 @@ def _read_and_merge_data(locs, tables, verbose=False, nuclei_limit=False, pathog
2679
2573
  metadata.drop(columns=object_label_cols, inplace=True)
2680
2574
 
2681
2575
  #Add prcfo column (plate row column field object)
2682
- metadata = metadata.assign(prcfo = lambda x: x['plate'] + '_' + x['row'] + '_' +x['col']+ '_' +x['field']+ '_' +x['object_label'])
2576
+ metadata = metadata.assign(prcfo = lambda x: x['plate'] + '_' + x['row_name'] + '_' +x['column_name']+ '_' +x['field']+ '_' +x['object_label'])
2683
2577
  metadata.set_index('prcfo', inplace=True)
2684
2578
 
2685
2579
  merged_df = metadata.merge(merged_df, left_index=True, right_index=True)
@@ -3030,8 +2924,7 @@ def generate_loaders(src, mode='train', image_size=224, batch_size=32, classes=[
3030
2924
  def generate_training_dataset(settings):
3031
2925
 
3032
2926
  # Function to filter png_list_df by prcfo present in df without merging
3033
- def filter_png_list(db_path, settings):
3034
- tables = ['cell', 'nucleus', 'pathogen', 'cytoplasm']
2927
+ def filter_png_list(db_path, settings, tables = ['cell', 'nucleus', 'pathogen', 'cytoplasm']):
3035
2928
  df, _ = _read_and_merge_data(locs=[db_path],
3036
2929
  tables=tables,
3037
2930
  verbose=False,
@@ -3053,9 +2946,8 @@ def generate_training_dataset(settings):
3053
2946
  return size
3054
2947
 
3055
2948
  # Measurement-based selection logic
3056
- def measurement_based_selection(settings, db_path):
2949
+ def measurement_based_selection(settings, db_path, tables = ['cell', 'nucleus', 'pathogen', 'cytoplasm']):
3057
2950
  class_paths_ls = []
3058
- tables = ['cell', 'nucleus', 'pathogen', 'cytoplasm']
3059
2951
  df, _ = _read_and_merge_data(locs=[db_path],
3060
2952
  tables=tables,
3061
2953
  verbose=False,
@@ -3068,7 +2960,7 @@ def generate_training_dataset(settings):
3068
2960
  treatment_loc=settings['class_metadata'])#, types=settings['metadata_type_by'])
3069
2961
  print('length df 2', len(df))
3070
2962
 
3071
- png_list_df = filter_png_list(db_path, settings)
2963
+ png_list_df = filter_png_list(db_path, settings, tables=settings['tables'])
3072
2964
 
3073
2965
  if settings['custom_measurement']:
3074
2966
  if isinstance(settings['custom_measurement'], list):
@@ -3101,8 +2993,8 @@ def generate_training_dataset(settings):
3101
2993
  # Metadata-based selection logic
3102
2994
  def metadata_based_selection(db_path, settings):
3103
2995
  class_paths_ls = []
3104
- df = filter_png_list(db_path, settings)
3105
-
2996
+ df = filter_png_list(db_path, settings, tables=settings['tables'])
2997
+
3106
2998
  df['metadata_based_class'] = pd.NA
3107
2999
  for i, class_ in enumerate(settings['classes']):
3108
3000
  ls = settings['class_metadata'][i]
@@ -3126,10 +3018,10 @@ def generate_training_dataset(settings):
3126
3018
  def annotation_based_selection(db_path, dst, settings):
3127
3019
  class_paths_ls = training_dataset_from_annotation(db_path, dst, settings['annotation_column'], annotated_classes=settings['annotated_classes'])
3128
3020
 
3129
- size = get_smallest_class_size(class_paths_ls, settings, 'annotation')
3130
- for i, class_paths in enumerate(class_paths_ls):
3131
- if len(class_paths) > size:
3132
- class_paths_ls[i] = random.sample(class_paths, size)
3021
+ #size = get_smallest_class_size(class_paths_ls, settings, 'annotation')
3022
+ #for i, class_paths in enumerate(class_paths_ls):
3023
+ # if len(class_paths) > size:
3024
+ # class_paths_ls[i] = random.sample(class_paths, size)
3133
3025
 
3134
3026
  return class_paths_ls
3135
3027
 
@@ -3137,6 +3029,13 @@ def generate_training_dataset(settings):
3137
3029
  from .utils import get_paths_from_db, annotate_conditions, save_settings
3138
3030
  from .settings import set_generate_training_dataset_defaults
3139
3031
 
3032
+ if 'nucleus' not in settings['tables']:
3033
+ settings['nuclei_limit'] = False
3034
+
3035
+ if 'pathogen' not in settings['tables']:
3036
+ settings['pathogen_limit'] = 0
3037
+ settings['uninfected'] = True
3038
+
3140
3039
  # Set default settings and save
3141
3040
  settings = set_generate_training_dataset_defaults(settings)
3142
3041
  save_settings(settings, 'cv_dataset', show=True)
@@ -3145,6 +3044,7 @@ def generate_training_dataset(settings):
3145
3044
 
3146
3045
  if isinstance(settings['src'], str):
3147
3046
  src = [settings['src']]
3047
+ settings['src'] = src
3148
3048
 
3149
3049
  for i, src in enumerate(settings['src']):
3150
3050
  db_path = os.path.join(src, 'measurements', 'measurements.db')
@@ -3170,7 +3070,7 @@ def generate_training_dataset(settings):
3170
3070
  class_paths_ls = metadata_based_selection(db_path, settings)
3171
3071
 
3172
3072
  elif settings['dataset_mode'] == 'measurement':
3173
- class_paths_ls = measurement_based_selection(settings, db_path)
3073
+ class_paths_ls = measurement_based_selection(settings, db_path, tables=settings['tables'])
3174
3074
 
3175
3075
  if class_path_list is None:
3176
3076
  class_path_list = [[] for _ in range(len(class_paths_ls))]
@@ -3180,22 +3080,72 @@ def generate_training_dataset(settings):
3180
3080
  class_path_list[idx].extend(class_paths_ls[idx])
3181
3081
 
3182
3082
  # Generate and return training and testing directories
3083
+ print('class_path_list',len(class_path_list))
3183
3084
  train_class_dir, test_class_dir = generate_dataset_from_lists(dst, class_data=class_path_list, classes=settings['classes'], test_split=settings['test_split'])
3184
3085
 
3185
3086
  return train_class_dir, test_class_dir
3186
3087
 
3187
3088
  def training_dataset_from_annotation(db_path, dst, annotation_column='test', annotated_classes=(1, 2)):
3188
3089
  all_paths = []
3189
-
3090
+
3190
3091
  # Connect to the database and retrieve the image paths and annotations
3191
3092
  print(f'Reading DataBase: {db_path}')
3192
3093
  with sqlite3.connect(db_path) as conn:
3193
3094
  cursor = conn.cursor()
3194
- # Prepare the query with parameterized placeholders for annotated_classes
3195
- placeholders = ','.join('?' * len(annotated_classes))
3196
- query = f"SELECT png_path, {annotation_column} FROM png_list WHERE {annotation_column} IN ({placeholders})"
3197
- cursor.execute(query, annotated_classes)
3095
+ # Retrieve all paths and annotations from the database
3096
+ query = f"SELECT png_path, {annotation_column} FROM png_list"
3097
+ cursor.execute(query)
3098
+
3099
+ while True:
3100
+ rows = cursor.fetchmany(1000)
3101
+ if not rows:
3102
+ break
3103
+ for row in rows:
3104
+ all_paths.append(row)
3105
+
3106
+ print('Total paths retrieved:', len(all_paths))
3107
+
3108
+ # Filter paths based on annotated_classes
3109
+ class_paths = []
3110
+ for class_ in annotated_classes:
3111
+ class_paths_temp = [path for path, annotation in all_paths if annotation == class_]
3112
+ class_paths.append(class_paths_temp)
3113
+ print(f'Found {len(class_paths_temp)} images in class {class_}')
3114
+
3115
+ # If only one class is provided, create an alternative list by sampling paths from all_paths that are not in the annotated class
3116
+ if len(annotated_classes) == 1:
3117
+ target_class = annotated_classes[0]
3118
+ count_target_class = len(class_paths[0])
3119
+ print(f'Annotated class: {target_class} with {count_target_class} images')
3120
+
3121
+ # Filter all_paths to exclude paths that belong to the target class
3122
+ alt_class_paths = [path for path, annotation in all_paths if annotation != target_class]
3123
+ print('Alternative paths available:', len(alt_class_paths))
3124
+
3125
+ # Randomly sample an equal number of images for the second class
3126
+ sampled_alt_class_paths = random.sample(alt_class_paths, min(count_target_class, len(alt_class_paths)))
3127
+ print(f'Sampled {len(sampled_alt_class_paths)} alternative images for balancing')
3128
+
3129
+ # Append this list as the second class
3130
+ class_paths.append(sampled_alt_class_paths)
3131
+
3132
+ print(f'Generated a list of lists from annotation of {len(class_paths)} classes')
3133
+ for i, ls in enumerate(class_paths):
3134
+ print(f'Class {i}: {len(ls)} images')
3135
+
3136
+ return class_paths
3198
3137
 
3138
+ def training_dataset_from_annotation_v2(db_path, dst, annotation_column='test', annotated_classes=(1, 2)):
3139
+ all_paths = []
3140
+
3141
+ # Connect to the database and retrieve the image paths and annotations
3142
+ print(f'Reading DataBase: {db_path}')
3143
+ with sqlite3.connect(db_path) as conn:
3144
+ cursor = conn.cursor()
3145
+ # Retrieve all paths and annotations from the database
3146
+ query = f"SELECT png_path, {annotation_column} FROM png_list"
3147
+ cursor.execute(query)
3148
+
3199
3149
  while True:
3200
3150
  rows = cursor.fetchmany(1000)
3201
3151
  if not rows:
@@ -3203,13 +3153,36 @@ def training_dataset_from_annotation(db_path, dst, annotation_column='test', ann
3203
3153
  for row in rows:
3204
3154
  all_paths.append(row)
3205
3155
 
3206
- # Filter paths based on annotation
3156
+ print('Total paths retrieved:', len(all_paths))
3157
+
3158
+ # Filter paths based on annotated_classes
3207
3159
  class_paths = []
3208
3160
  for class_ in annotated_classes:
3209
3161
  class_paths_temp = [path for path, annotation in all_paths if annotation == class_]
3210
3162
  class_paths.append(class_paths_temp)
3163
+ print(f'Found {len(class_paths_temp)} images in class {class_}')
3164
+
3165
+ # If only one class is provided, create an alternative list by sampling paths from all_paths that are not in the annotated class
3166
+ if len(annotated_classes) == 1:
3167
+ target_class = annotated_classes[0]
3168
+ count_target_class = len(class_paths[0])
3169
+ print(f'Annotated class: {target_class} with {count_target_class} images')
3170
+
3171
+ # Filter all_paths to exclude paths that belong to the target class
3172
+ alt_class_paths = [path for path, annotation in all_paths if annotation != target_class]
3173
+ print('Alternative paths available:', len(alt_class_paths))
3174
+
3175
+ # Randomly sample an equal number of images for the second class
3176
+ sampled_alt_class_paths = random.sample(alt_class_paths, min(count_target_class, len(alt_class_paths)))
3177
+ print(f'Sampled {len(sampled_alt_class_paths)} alternative images for balancing')
3178
+
3179
+ # Append this list as the second class
3180
+ class_paths.append(sampled_alt_class_paths)
3211
3181
 
3212
3182
  print(f'Generated a list of lists from annotation of {len(class_paths)} classes')
3183
+ for i, ls in enumerate(class_paths):
3184
+ print(f'Class {i}: {len(ls)} images')
3185
+
3213
3186
  return class_paths
3214
3187
 
3215
3188
  def generate_dataset_from_lists(dst, class_data, classes, test_split=0.1):
@@ -3228,8 +3201,9 @@ def generate_dataset_from_lists(dst, class_data, classes, test_split=0.1):
3228
3201
  test_class_dir = os.path.join(dst, f'test/{cls}')
3229
3202
  os.makedirs(train_class_dir, exist_ok=True)
3230
3203
  os.makedirs(test_class_dir, exist_ok=True)
3231
-
3204
+
3232
3205
  # Split the data
3206
+ print('data',len(data), test_split)
3233
3207
  train_data, test_data = train_test_split(data, test_size=test_split, shuffle=True, random_state=42)
3234
3208
 
3235
3209
  # Copy train files