spacr 0.3.61__tar.gz → 0.3.64__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 (296) hide show
  1. {spacr-0.3.61/spacr.egg-info → spacr-0.3.64}/PKG-INFO +1 -1
  2. spacr-0.3.64/notebooks/old/.ipynb_checkpoints/Untitled-checkpoint.ipynb +337 -0
  3. spacr-0.3.64/notebooks/old/Untitled.ipynb +366 -0
  4. spacr-0.3.64/notebooks/old/interperate_vision_classes.ipynb +1353 -0
  5. {spacr-0.3.61 → spacr-0.3.64}/setup.py +1 -1
  6. {spacr-0.3.61 → spacr-0.3.64}/spacr/io.py +133 -3
  7. {spacr-0.3.61 → spacr-0.3.64}/spacr/ml.py +205 -0
  8. {spacr-0.3.61 → spacr-0.3.64}/spacr/plot.py +48 -0
  9. {spacr-0.3.61 → spacr-0.3.64}/spacr/settings.py +64 -0
  10. {spacr-0.3.61 → spacr-0.3.64}/spacr/submodules.py +298 -1
  11. {spacr-0.3.61 → spacr-0.3.64}/spacr/utils.py +58 -2
  12. {spacr-0.3.61 → spacr-0.3.64/spacr.egg-info}/PKG-INFO +1 -1
  13. {spacr-0.3.61 → spacr-0.3.64}/spacr.egg-info/SOURCES.txt +2 -0
  14. spacr-0.3.61/notebooks/old/interperate_vision_classes.ipynb +0 -831
  15. {spacr-0.3.61 → spacr-0.3.64}/.readthedocs.yaml +0 -0
  16. {spacr-0.3.61 → spacr-0.3.64}/LICENSE +0 -0
  17. {spacr-0.3.61 → spacr-0.3.64}/MANIFEST.in +0 -0
  18. {spacr-0.3.61 → spacr-0.3.64}/README.rst +0 -0
  19. {spacr-0.3.61 → spacr-0.3.64}/deploy_docs.sh +0 -0
  20. {spacr-0.3.61 → spacr-0.3.64}/docs/requirements.txt +0 -0
  21. {spacr-0.3.61 → spacr-0.3.64}/docs/source/Makefile +0 -0
  22. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/doctrees/environment.pickle +0 -0
  23. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_modules/index.html +0 -0
  24. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_modules/spacr/app_annotate.html +0 -0
  25. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_modules/spacr/app_classify.html +0 -0
  26. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_modules/spacr/app_make_masks.html +0 -0
  27. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_modules/spacr/app_mask.html +0 -0
  28. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_modules/spacr/app_measure.html +0 -0
  29. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_modules/spacr/app_sequencing.html +0 -0
  30. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_modules/spacr/app_umap.html +0 -0
  31. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_modules/spacr/core.html +0 -0
  32. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_modules/spacr/deep_spacr.html +0 -0
  33. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_modules/spacr/graph_learning.html +0 -0
  34. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_modules/spacr/gui.html +0 -0
  35. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_modules/spacr/gui_core.html +0 -0
  36. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_modules/spacr/gui_elements.html +0 -0
  37. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_modules/spacr/gui_utils.html +0 -0
  38. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_modules/spacr/io.html +0 -0
  39. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_modules/spacr/logger.html +0 -0
  40. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_modules/spacr/measure.html +0 -0
  41. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_modules/spacr/plot.html +0 -0
  42. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_modules/spacr/sequencing.html +0 -0
  43. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_modules/spacr/settings.html +0 -0
  44. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_modules/spacr/sim.html +0 -0
  45. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_modules/spacr/timelapse.html +0 -0
  46. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_modules/spacr/utils.html +0 -0
  47. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_sources/index.rst.txt +0 -0
  48. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_sources/modules.rst.txt +0 -0
  49. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_sources/spacr.rst.txt +0 -0
  50. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_static/_sphinx_javascript_frameworks_compat.js +0 -0
  51. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_static/basic.css +0 -0
  52. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_static/css/badge_only.css +0 -0
  53. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_static/css/fonts/Roboto-Slab-Bold.woff +0 -0
  54. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_static/css/fonts/Roboto-Slab-Bold.woff2 +0 -0
  55. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_static/css/fonts/Roboto-Slab-Regular.woff +0 -0
  56. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_static/css/fonts/Roboto-Slab-Regular.woff2 +0 -0
  57. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_static/css/fonts/fontawesome-webfont.eot +0 -0
  58. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_static/css/fonts/fontawesome-webfont.svg +0 -0
  59. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_static/css/fonts/fontawesome-webfont.ttf +0 -0
  60. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_static/css/fonts/fontawesome-webfont.woff +0 -0
  61. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_static/css/fonts/fontawesome-webfont.woff2 +0 -0
  62. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_static/css/fonts/lato-bold-italic.woff +0 -0
  63. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_static/css/fonts/lato-bold-italic.woff2 +0 -0
  64. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_static/css/fonts/lato-bold.woff +0 -0
  65. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_static/css/fonts/lato-bold.woff2 +0 -0
  66. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_static/css/fonts/lato-normal-italic.woff +0 -0
  67. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_static/css/fonts/lato-normal-italic.woff2 +0 -0
  68. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_static/css/fonts/lato-normal.woff +0 -0
  69. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_static/css/fonts/lato-normal.woff2 +0 -0
  70. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_static/css/theme.css +0 -0
  71. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_static/doctools.js +0 -0
  72. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_static/documentation_options.js +0 -0
  73. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_static/file.png +0 -0
  74. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_static/jquery.js +0 -0
  75. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_static/js/badge_only.js +0 -0
  76. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_static/js/html5shiv-printshiv.min.js +0 -0
  77. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_static/js/html5shiv.min.js +0 -0
  78. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_static/js/theme.js +0 -0
  79. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_static/language_data.js +0 -0
  80. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_static/minus.png +0 -0
  81. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_static/plus.png +0 -0
  82. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_static/pygments.css +0 -0
  83. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_static/searchtools.js +0 -0
  84. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/_static/sphinx_highlight.js +0 -0
  85. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/genindex.html +0 -0
  86. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/index.html +0 -0
  87. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/modules.html +0 -0
  88. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/objects.inv +0 -0
  89. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/py-modindex.html +0 -0
  90. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/search.html +0 -0
  91. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/searchindex.js +0 -0
  92. {spacr-0.3.61 → spacr-0.3.64}/docs/source/_build/html/spacr.html +0 -0
  93. {spacr-0.3.61 → spacr-0.3.64}/docs/source/conf.py +0 -0
  94. {spacr-0.3.61 → spacr-0.3.64}/docs/source/index.rst +0 -0
  95. {spacr-0.3.61 → spacr-0.3.64}/docs/source/make.bat +0 -0
  96. {spacr-0.3.61 → spacr-0.3.64}/docs/source/modules.rst +0 -0
  97. {spacr-0.3.61 → spacr-0.3.64}/docs/source/spacr.rst +0 -0
  98. {spacr-0.3.61 → spacr-0.3.64}/environment.yaml +0 -0
  99. {spacr-0.3.61 → spacr-0.3.64}/fonts/OpenSans-Regular.ttf +0 -0
  100. {spacr-0.3.61 → spacr-0.3.64}/notebooks/.ipynb_checkpoints/4_spacr_annotate-checkpoint.ipynb +0 -0
  101. {spacr-0.3.61 → spacr-0.3.64}/notebooks/1_spacr_generate_masks.ipynb +0 -0
  102. {spacr-0.3.61 → spacr-0.3.64}/notebooks/2_spacr_generate_mesurments_crop_images.ipynb +0 -0
  103. {spacr-0.3.61 → spacr-0.3.64}/notebooks/3a_spacr_machine_learning.ipynb +0 -0
  104. {spacr-0.3.61 → spacr-0.3.64}/notebooks/3b_spacr_computer_vision.ipynb +0 -0
  105. {spacr-0.3.61 → spacr-0.3.64}/notebooks/4_spacr_annotate.ipynb +0 -0
  106. {spacr-0.3.61 → spacr-0.3.64}/notebooks/old/.ipynb_checkpoints/figure_2-checkpoint.ipynb +0 -0
  107. {spacr-0.3.61 → spacr-0.3.64}/notebooks/old/.ipynb_checkpoints/interperate_vision_classes-checkpoint.ipynb +0 -0
  108. {spacr-0.3.61 → spacr-0.3.64}/notebooks/old/.ipynb_checkpoints/spacr_image_umap-checkpoint.ipynb +0 -0
  109. {spacr-0.3.61 → spacr-0.3.64}/notebooks/old/cv_scoring_nb.ipynb +0 -0
  110. {spacr-0.3.61 → spacr-0.3.64}/notebooks/old/deep_learning_spacr.ipynb +0 -0
  111. {spacr-0.3.61 → spacr-0.3.64}/notebooks/old/figure_2.ipynb +0 -0
  112. {spacr-0.3.61 → spacr-0.3.64}/notebooks/old/figure_3-Copy1.ipynb +0 -0
  113. {spacr-0.3.61 → spacr-0.3.64}/notebooks/old/figure_3.ipynb +0 -0
  114. {spacr-0.3.61 → spacr-0.3.64}/notebooks/old/machine_learning_spacr_nb.ipynb +0 -0
  115. {spacr-0.3.61 → spacr-0.3.64}/notebooks/old/spacr_0.1_all_settings_git.ipynb +0 -0
  116. {spacr-0.3.61 → spacr-0.3.64}/notebooks/old/spacr_0.1_minimal.ipynb +0 -0
  117. {spacr-0.3.61 → spacr-0.3.64}/notebooks/old/spacr_image_umap.ipynb +0 -0
  118. {spacr-0.3.61 → spacr-0.3.64}/path/home/carruthers/datasets/plate1/measurements/measurements.db +0 -0
  119. {spacr-0.3.61 → spacr-0.3.64}/path/home/carruthers/datasets/plate1/settings/measure_crop_settings.csv +0 -0
  120. {spacr-0.3.61 → spacr-0.3.64}/path/settings/preprocess_generate_masks_settings.csv +0 -0
  121. {spacr-0.3.61 → spacr-0.3.64}/requirements.txt +0 -0
  122. {spacr-0.3.61 → spacr-0.3.64}/settings/measure_crop_settings.csv +0 -0
  123. {spacr-0.3.61 → spacr-0.3.64}/setup.cfg +0 -0
  124. {spacr-0.3.61 → spacr-0.3.64}/setup_docs.sh +0 -0
  125. {spacr-0.3.61 → spacr-0.3.64}/source/conf.py +0 -0
  126. {spacr-0.3.61 → spacr-0.3.64}/source/index.rst +0 -0
  127. {spacr-0.3.61 → spacr-0.3.64}/source/modules.rst +0 -0
  128. {spacr-0.3.61 → spacr-0.3.64}/source/setup.rst +0 -0
  129. {spacr-0.3.61 → spacr-0.3.64}/source/spacr.rst +0 -0
  130. {spacr-0.3.61 → spacr-0.3.64}/spacr/__init__.py +0 -0
  131. {spacr-0.3.61 → spacr-0.3.64}/spacr/__main__.py +0 -0
  132. {spacr-0.3.61 → spacr-0.3.64}/spacr/app_annotate.py +0 -0
  133. {spacr-0.3.61 → spacr-0.3.64}/spacr/app_classify.py +0 -0
  134. {spacr-0.3.61 → spacr-0.3.64}/spacr/app_make_masks.py +0 -0
  135. {spacr-0.3.61 → spacr-0.3.64}/spacr/app_mask.py +0 -0
  136. {spacr-0.3.61 → spacr-0.3.64}/spacr/app_measure.py +0 -0
  137. {spacr-0.3.61 → spacr-0.3.64}/spacr/app_sequencing.py +0 -0
  138. {spacr-0.3.61 → spacr-0.3.64}/spacr/app_umap.py +0 -0
  139. {spacr-0.3.61 → spacr-0.3.64}/spacr/cellpose.py +0 -0
  140. {spacr-0.3.61 → spacr-0.3.64}/spacr/chat_bot.py +0 -0
  141. {spacr-0.3.61 → spacr-0.3.64}/spacr/core.py +0 -0
  142. {spacr-0.3.61 → spacr-0.3.64}/spacr/deep_spacr.py +0 -0
  143. {spacr-0.3.61 → spacr-0.3.64}/spacr/gui.py +0 -0
  144. {spacr-0.3.61 → spacr-0.3.64}/spacr/gui_core.py +0 -0
  145. {spacr-0.3.61 → spacr-0.3.64}/spacr/gui_elements.py +0 -0
  146. {spacr-0.3.61 → spacr-0.3.64}/spacr/gui_utils.py +0 -0
  147. {spacr-0.3.61 → spacr-0.3.64}/spacr/logger.py +0 -0
  148. {spacr-0.3.61 → spacr-0.3.64}/spacr/measure.py +0 -0
  149. {spacr-0.3.61 → spacr-0.3.64}/spacr/mediar.py +0 -0
  150. {spacr-0.3.61 → spacr-0.3.64}/spacr/openai.py +0 -0
  151. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/.gitignore +0 -0
  152. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/LICENSE +0 -0
  153. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/README.md +0 -0
  154. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/SetupDict.py +0 -0
  155. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/config/baseline.json +0 -0
  156. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/config/mediar_example.json +0 -0
  157. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/config/pred/pred_mediar.json +0 -0
  158. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/config/step1_pretraining/phase1.json +0 -0
  159. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/config/step1_pretraining/phase2.json +0 -0
  160. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/config/step2_finetuning/finetuning1.json +0 -0
  161. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/config/step2_finetuning/finetuning2.json +0 -0
  162. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/config/step3_prediction/base_prediction.json +0 -0
  163. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/config/step3_prediction/ensemble_tta.json +0 -0
  164. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/core/BasePredictor.py +0 -0
  165. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/core/BaseTrainer.py +0 -0
  166. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/core/Baseline/Predictor.py +0 -0
  167. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/core/Baseline/Trainer.py +0 -0
  168. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/core/Baseline/__init__.py +0 -0
  169. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/core/Baseline/utils.py +0 -0
  170. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/core/MEDIAR/EnsemblePredictor.py +0 -0
  171. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/core/MEDIAR/Predictor.py +0 -0
  172. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/core/MEDIAR/Trainer.py +0 -0
  173. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/core/MEDIAR/__init__.py +0 -0
  174. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/core/MEDIAR/utils.py +0 -0
  175. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/core/__init__.py +0 -0
  176. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/core/utils.py +0 -0
  177. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/evaluate.py +0 -0
  178. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/generate_mapping.py +0 -0
  179. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/image/examples/img1.tiff +0 -0
  180. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/image/examples/img2.tif +0 -0
  181. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/image/failure_cases.png +0 -0
  182. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/image/mediar_framework.png +0 -0
  183. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/image/mediar_model.PNG +0 -0
  184. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/image/mediar_results.png +0 -0
  185. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/main.py +0 -0
  186. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/predict.py +0 -0
  187. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/requirements.txt +0 -0
  188. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/train_tools/__init__.py +0 -0
  189. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/train_tools/data_utils/__init__.py +0 -0
  190. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/train_tools/data_utils/custom/CellAware.py +0 -0
  191. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/train_tools/data_utils/custom/LoadImage.py +0 -0
  192. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/train_tools/data_utils/custom/NormalizeImage.py +0 -0
  193. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/train_tools/data_utils/custom/__init__.py +0 -0
  194. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/train_tools/data_utils/custom/modalities.pkl +0 -0
  195. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/train_tools/data_utils/datasetter.py +0 -0
  196. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/train_tools/data_utils/transforms.py +0 -0
  197. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/train_tools/data_utils/utils.py +0 -0
  198. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/train_tools/measures.py +0 -0
  199. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/train_tools/models/MEDIARFormer.py +0 -0
  200. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/train_tools/models/__init__.py +0 -0
  201. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/MEDIAR/train_tools/utils.py +0 -0
  202. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/data/lopit.csv +0 -0
  203. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/data/toxoplasma_metadata.csv +0 -0
  204. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/OFL.txt +0 -0
  205. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/OpenSans-Italic-VariableFont_wdth,wght.ttf +0 -0
  206. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/OpenSans-VariableFont_wdth,wght.ttf +0 -0
  207. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/README.txt +0 -0
  208. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/static/OpenSans-Bold.ttf +0 -0
  209. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/static/OpenSans-BoldItalic.ttf +0 -0
  210. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/static/OpenSans-ExtraBold.ttf +0 -0
  211. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/static/OpenSans-ExtraBoldItalic.ttf +0 -0
  212. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/static/OpenSans-Italic.ttf +0 -0
  213. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/static/OpenSans-Light.ttf +0 -0
  214. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/static/OpenSans-LightItalic.ttf +0 -0
  215. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/static/OpenSans-Medium.ttf +0 -0
  216. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/static/OpenSans-MediumItalic.ttf +0 -0
  217. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/static/OpenSans-Regular.ttf +0 -0
  218. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/static/OpenSans-SemiBold.ttf +0 -0
  219. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/static/OpenSans-SemiBoldItalic.ttf +0 -0
  220. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/static/OpenSans_Condensed-Bold.ttf +0 -0
  221. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/static/OpenSans_Condensed-BoldItalic.ttf +0 -0
  222. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/static/OpenSans_Condensed-ExtraBold.ttf +0 -0
  223. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/static/OpenSans_Condensed-ExtraBoldItalic.ttf +0 -0
  224. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/static/OpenSans_Condensed-Italic.ttf +0 -0
  225. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/static/OpenSans_Condensed-Light.ttf +0 -0
  226. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/static/OpenSans_Condensed-LightItalic.ttf +0 -0
  227. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/static/OpenSans_Condensed-Medium.ttf +0 -0
  228. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/static/OpenSans_Condensed-MediumItalic.ttf +0 -0
  229. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/static/OpenSans_Condensed-Regular.ttf +0 -0
  230. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/static/OpenSans_Condensed-SemiBold.ttf +0 -0
  231. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/static/OpenSans_Condensed-SemiBoldItalic.ttf +0 -0
  232. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-Bold.ttf +0 -0
  233. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-BoldItalic.ttf +0 -0
  234. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-ExtraBold.ttf +0 -0
  235. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-ExtraBoldItalic.ttf +0 -0
  236. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-Italic.ttf +0 -0
  237. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-Light.ttf +0 -0
  238. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-LightItalic.ttf +0 -0
  239. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-Medium.ttf +0 -0
  240. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-MediumItalic.ttf +0 -0
  241. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-Regular.ttf +0 -0
  242. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-SemiBold.ttf +0 -0
  243. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/font/open_sans/static/OpenSans_SemiCondensed-SemiBoldItalic.ttf +0 -0
  244. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/icons/abort.png +0 -0
  245. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/icons/annotate.png +0 -0
  246. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/icons/cellpose_all.png +0 -0
  247. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/icons/cellpose_masks.png +0 -0
  248. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/icons/classify.png +0 -0
  249. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/icons/convert.png +0 -0
  250. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/icons/default.png +0 -0
  251. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/icons/dna_matrix.mp4 +0 -0
  252. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/icons/download.png +0 -0
  253. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/icons/logo.pdf +0 -0
  254. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/icons/logo_spacr.png +0 -0
  255. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/icons/logo_spacr_1.png +0 -0
  256. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/icons/make_masks.png +0 -0
  257. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/icons/map_barcodes.png +0 -0
  258. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/icons/mask.png +0 -0
  259. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/icons/measure.png +0 -0
  260. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/icons/ml_analyze.png +0 -0
  261. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/icons/plaque.png +0 -0
  262. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/icons/recruitment.png +0 -0
  263. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/icons/regression.png +0 -0
  264. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/icons/run.png +0 -0
  265. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/icons/sequencing.png +0 -0
  266. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/icons/settings.png +0 -0
  267. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/icons/train_cellpose.png +0 -0
  268. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/icons/umap.png +0 -0
  269. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/images/plate1_E01_T0001F001L01A01Z01C02.tif +0 -0
  270. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/images/plate1_E01_T0001F001L01A02Z01C01.tif +0 -0
  271. {spacr-0.3.61 → spacr-0.3.64}/spacr/resources/images/plate1_E01_T0001F001L01A03Z01C03.tif +0 -0
  272. {spacr-0.3.61 → spacr-0.3.64}/spacr/sequencing.py +0 -0
  273. {spacr-0.3.61 → spacr-0.3.64}/spacr/sim.py +0 -0
  274. {spacr-0.3.61 → spacr-0.3.64}/spacr/timelapse.py +0 -0
  275. {spacr-0.3.61 → spacr-0.3.64}/spacr/toxo.py +0 -0
  276. {spacr-0.3.61 → spacr-0.3.64}/spacr/version.py +0 -0
  277. {spacr-0.3.61 → spacr-0.3.64}/spacr.egg-info/dependency_links.txt +0 -0
  278. {spacr-0.3.61 → spacr-0.3.64}/spacr.egg-info/entry_points.txt +0 -0
  279. {spacr-0.3.61 → spacr-0.3.64}/spacr.egg-info/requires.txt +0 -0
  280. {spacr-0.3.61 → spacr-0.3.64}/spacr.egg-info/top_level.txt +0 -0
  281. {spacr-0.3.61 → spacr-0.3.64}/tests/test_annotate_app.py +0 -0
  282. {spacr-0.3.61 → spacr-0.3.64}/tests/test_core.py +0 -0
  283. {spacr-0.3.61 → spacr-0.3.64}/tests/test_gui_classify_app.py +0 -0
  284. {spacr-0.3.61 → spacr-0.3.64}/tests/test_gui_mask_app.py +0 -0
  285. {spacr-0.3.61 → spacr-0.3.64}/tests/test_gui_measure_app.py +0 -0
  286. {spacr-0.3.61 → spacr-0.3.64}/tests/test_gui_sim_app.py +0 -0
  287. {spacr-0.3.61 → spacr-0.3.64}/tests/test_gui_utils.py +0 -0
  288. {spacr-0.3.61 → spacr-0.3.64}/tests/test_io.py +0 -0
  289. {spacr-0.3.61 → spacr-0.3.64}/tests/test_mask_app.py +0 -0
  290. {spacr-0.3.61 → spacr-0.3.64}/tests/test_measure.py +0 -0
  291. {spacr-0.3.61 → spacr-0.3.64}/tests/test_plot.py +0 -0
  292. {spacr-0.3.61 → spacr-0.3.64}/tests/test_sim.py +0 -0
  293. {spacr-0.3.61 → spacr-0.3.64}/tests/test_timelapse.py +0 -0
  294. {spacr-0.3.61 → spacr-0.3.64}/tests/test_train.py +0 -0
  295. {spacr-0.3.61 → spacr-0.3.64}/tests/test_umap.py +0 -0
  296. {spacr-0.3.61 → spacr-0.3.64}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: spacr
3
- Version: 0.3.61
3
+ Version: 0.3.64
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
@@ -0,0 +1,337 @@
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": null,
6
+ "id": "0a6d929d",
7
+ "metadata": {},
8
+ "outputs": [],
9
+ "source": [
10
+ "from spacr.plot import graph_importance\n",
11
+ "%matplotlib inline\n",
12
+ "\n",
13
+ "csvs = ['/nas_mnt/carruthers/Einar/tsg101_screen/TSG101SCREEN_20240810_132824/plate1/results/feature_importance_compartment.csv',\n",
14
+ " '/nas_mnt/carruthers/Einar/tsg101_screen/TSG101SCREEN_20240824_072829/plate2/results/feature_importance_compartment.csv',\n",
15
+ " '/nas_mnt/carruthers/Einar/tsg101_screen/TSG101SCREEN_20240825_094106/plate3/results/feature_importance_compartment.csv',\n",
16
+ " '/nas_mnt/carruthers/Einar/tsg101_screen/TSG101SCREEN_20240826_140251/plate4/results/feature_importance_compartment.csv']\n",
17
+ "\n",
18
+ "settings = {'csvs':csvs,\n",
19
+ " 'grouping_column':'compartment',\n",
20
+ " 'data_column':'compartment_importance_sum',\n",
21
+ " 'graph_type':'jitter_bar',\n",
22
+ " 'save':False}\n",
23
+ "\n",
24
+ "graph_importance(settings)"
25
+ ]
26
+ },
27
+ {
28
+ "cell_type": "code",
29
+ "execution_count": null,
30
+ "id": "858a77a9",
31
+ "metadata": {
32
+ "scrolled": false
33
+ },
34
+ "outputs": [],
35
+ "source": [
36
+ "import pandas as pd\n",
37
+ "from spacr.plot import spacrGraph\n",
38
+ "import matplotlib.pyplot as plt\n",
39
+ "%matplotlib inline\n",
40
+ "\n",
41
+ "srcs = ['/nas_mnt/carruthers/Einar/tsg101_screen/TSG101SCREEN_20240810_132824/plate1/results/feature_importance_compartment.csv',\n",
42
+ " '/nas_mnt/carruthers/Einar/tsg101_screen/TSG101SCREEN_20240824_072829/plate2/results/feature_importance_compartment.csv',\n",
43
+ " '/nas_mnt/carruthers/Einar/tsg101_screen/TSG101SCREEN_20240825_094106/plate3/results/feature_importance_compartment.csv',\n",
44
+ " '/nas_mnt/carruthers/Einar/tsg101_screen/TSG101SCREEN_20240826_140251/plate4/results/feature_importance_compartment.csv']\n",
45
+ "\n",
46
+ "dfs = []\n",
47
+ "for path in srcs:\n",
48
+ " dft = pd.read_csv(path)\n",
49
+ " dfs.append(dft)\n",
50
+ "\n",
51
+ "df = pd.concat(dfs)\n",
52
+ "display(df)\n",
53
+ "\n",
54
+ "spacr_graph = spacrGraph(\n",
55
+ " df=df, \n",
56
+ " grouping_column='compartment', \n",
57
+ " data_column='compartment_importance_sum', \n",
58
+ " graph_type='jitter_bar', \n",
59
+ " graph_name='compartment', \n",
60
+ " summary_func='mean', \n",
61
+ " colors=None, \n",
62
+ " output_dir='/nas_mnt/carruthers/Einar/tsg101_screen/TSG101SCREEN_20240810_132824/plate1/results', \n",
63
+ " save=True, \n",
64
+ " y_lim=None, \n",
65
+ " error_bar_type='std', \n",
66
+ " representation='object',\n",
67
+ " theme='pastel', \n",
68
+ ")\n",
69
+ "\n",
70
+ "\n",
71
+ "# Create the plot\n",
72
+ "spacr_graph.create_plot()\n",
73
+ "\n",
74
+ "# Get the figure object if needed\n",
75
+ "fig = spacr_graph.get_figure()\n",
76
+ "plt.show()"
77
+ ]
78
+ },
79
+ {
80
+ "cell_type": "code",
81
+ "execution_count": null,
82
+ "id": "0f756080",
83
+ "metadata": {
84
+ "scrolled": false
85
+ },
86
+ "outputs": [],
87
+ "source": [
88
+ "from spacr.submodules import analyze_endodyogeny\n",
89
+ "%matplotlib inline\n",
90
+ "\n",
91
+ "settings = {\n",
92
+ " 'src': '/nas_mnt/carruthers/Einar/tsg101_screen/TSG101SCREEN_20240810_132824/plate1/',\n",
93
+ " 'tables': ['cell', 'nucleus', 'pathogen', 'cytoplasm'],\n",
94
+ " 'cell_types': ['Hela'],\n",
95
+ " 'cell_plate_metadata': None,\n",
96
+ " 'pathogen_types': ['nc', 'pc'],\n",
97
+ " 'pathogen_plate_metadata': [['c1'], ['c2']],\n",
98
+ " 'treatments': None,\n",
99
+ " 'treatment_plate_metadata': None,\n",
100
+ " 'min_area_bin': 500,\n",
101
+ " 'group_column': 'pathogen',\n",
102
+ " 'compartment': 'pathogen',\n",
103
+ " 'pathogen_limit': 1,\n",
104
+ " 'nuclei_limit': 1000,\n",
105
+ " 'level': 'well',\n",
106
+ " 'um_per_px':0.1,\n",
107
+ " 'max_bins':5,\n",
108
+ " 'save':False,\n",
109
+ " 'verbose': True}\n",
110
+ "\n",
111
+ "# Run the analysis\n",
112
+ "chi2, p = analyze_endodyogeny(settings)\n",
113
+ "print(f\"Chi-squared statistic: {chi2}, p-value: {p}\")\n"
114
+ ]
115
+ },
116
+ {
117
+ "cell_type": "code",
118
+ "execution_count": 13,
119
+ "id": "0d73aa58",
120
+ "metadata": {
121
+ "scrolled": false
122
+ },
123
+ "outputs": [
124
+ {
125
+ "name": "stdout",
126
+ "output_type": "stream",
127
+ "text": [
128
+ "cell: 60816\n",
129
+ "nucleus: 80889\n",
130
+ "pathogen: 111317\n",
131
+ "cytoplasm: 60816\n",
132
+ "png_list: 60816\n",
133
+ "cells: 60816, cells grouped: 60816\n",
134
+ "cytoplasms: 60816, cytoplasms grouped: 60816\n",
135
+ "nucleus: 80889, nucleus grouped: 60816\n",
136
+ "pathogens: 37541, pathogens grouped: 37541\n",
137
+ "png_list: 60816, png_list grouped: 60816\n",
138
+ "Added png_list columns: Index(['test', 'test_2'], dtype='object'), Index(['png_path'], dtype='object')\n",
139
+ "Generated dataframe with: 794 columns and 37541 rows\n",
140
+ "Chi-squared test statistic (raw data): 0.0000\n",
141
+ "p-value (raw data): 1.0000e+00\n",
142
+ "Chi-squared results saved to /nas_mnt/carruthers/Einar/tsg101_screen/TSG101SCREEN_20240810_132824/plate1/results/class_chi_squared_results.csv\n",
143
+ "Annotated data saved to /nas_mnt/carruthers/Einar/tsg101_screen/TSG101SCREEN_20240810_132824/plate1/results/class_chi_squared_data.csv\n"
144
+ ]
145
+ },
146
+ {
147
+ "data": {
148
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAABLMAAALACAYAAABo5DA3AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAABj3klEQVR4nO3dd5xU1f0//teCsDSBKE0UBXtHI18R0cREFEuwxFiwoNgSu6JGjQU7Ro2axEI0sSUSjT3Ggog1lhh7NFYsGCMgIqAgIHB/f/hjPqws1ZXlmufz8djHgzlz7p33nbkzw772nHOriqIoAgAAAAAl0KC+CwAAAACABSXMAgAAAKA0hFkAAAAAlIYwCwAAAIDSEGYBAAAAUBrCLAAAAABKQ5gFAAAAQGkIswAAAAAoDWEWAAAAAKUhzAJYQJ07d85+++1X32XM05tvvpmtt946rVq1SlVVVe64447F9thleH7qwn777ZfOnTsv9sds0aLFYn3Mb6unn346jRs3znvvvVffpcA3pqqqKqeffnrl9rXXXpuqqqq8++67C7yPjz/+OM2bN88999xT9wUCwNckzAIWyaz/GM/6adKkSVZfffUcfvjhGT16dH2Xt8ieeOKJnH766Rk/fnx9l7JI9t133/zrX//KOeeckz/+8Y/p1q3bHH0uuuiiVFVV5YEHHpjrfq666qpUVVXlr3/96zdZ7hJj9nO5qqoqzZs3z9prr52zzz47kydPru/yFquZM2fm+uuvz1ZbbZU2bdqkUaNGadeuXbbeeutceeWVmTp1an2X+LWcfPLJ6du3b1ZaaaVK2xZbbJGqqqqsttpqtW4zbNiwyrlxyy23LK5S691HH32Uo446KmuuuWaaNm2adu3aZeONN84JJ5yQzz77rNJvv/32q/H+adGiRVZeeeX85Cc/ya233pqZM2fW41GwqJZddtkceOCBOfXUU+u7FACYw1L1XQBQbmeeeWa6dOmSKVOm5O9//3uuuOKK3HPPPXn55ZfTrFmz+i5voT3xxBM544wzst9++6V169Y17nv99dfToMGS+zeAzz//PE8++WROPvnkHH744XPtt8cee+T444/PkCFD0qtXr1r7DBkyJMsuu2y23Xbbb6rcJc5WW22Vfv36JUk+++yzPPbYYzn11FPz4osv5uabb670u+qqq761v5x//vnn2XnnnTN06NBsuummOe6449K+ffuMGzcujzzySA499ND84x//yB/+8If6LnWRvPDCC3nggQfyxBNPzHFfkyZN8tZbb+Xpp5/OxhtvXOO+G264IU2aNMmUKVMWV6n1bty4cenWrVsmTpyY/fffP2uuuWY+/vjjvPTSS7niiityyCGH1BgtWF1dnd///vdJvjyP3nvvvdx11135yU9+ki222CJ33nlnWrZsWV+HwyL62c9+lt/85jd58MEH88Mf/rC+ywGACmEW8LVsu+22ldE/Bx54YJZddtlcdNFFufPOO9O3b99at5k0aVKaN2++OMucrwWpqbq6ejFVs2g++uijJJkjhPuqjh075gc/+EFuu+22XHHFFXMc1wcffJBHH300Bx98cBo1avRNlbvEWX311bP33ntXbv/sZz/LtGnTctttt2XKlClp0qRJknyrn5NjjjkmQ4cOzSWXXJKjjjqqxn3HHnts3nzzzQwbNmye+5g+fXpmzpyZxo0bf5OlLpJrrrkmK664YjbZZJM57ltllVUyffr0/PnPf64RZk2ZMiW33357tt9++9x6662Ls9w6sd9+++Xdd9/Nww8/vFDb/eEPf8jIkSPz+OOPZ9NNN61x38SJE+d4fZdaaqka758kOfvss3PeeeflpJNOykEHHZSbbrppkY6hriyJ3z1LurXWWivrrrturr32WmEWAEuUJXeIAVBKs/6z+8477yT5v7V+RowYke222y5LL7109tprryRf/mJx7LHHplOnTqmurs4aa6yRCy+8MEVR1NhnVVVVDj/88Nxwww1ZY4010qRJk2y00UZ59NFH53j8559/Pttuu21atmyZFi1aZMstt8xTTz1Vo8+sKZKzRpq0a9cuK6ywQk4//fQcf/zxSZIuXbpUpszMWmOktjWh3n777ey6665ZZpll0qxZs2yyySa5++67a/R5+OGHU1VVlb/85S8555xzssIKK6RJkybZcsst89Zbby3Q8zq/4zr99NMr06aOP/74VFVVzXNdp7333jsTJkyYo9YkufHGGzNz5syFfp2+6vTTT09VVdUc7bWt3dK5c+f86Ec/ysMPP5xu3bqladOmWW+99Sq/gN92221Zb731Kq/9888/P8d+X3vttfzkJz/JMssskyZNmqRbt25fe5pkhw4dUlVVlaWW+r+//Xx1zax33303VVVVufDCC3PllVdmlVVWSXV1df7f//t/+ec//1ljf6NGjUr//v2zwgorpLq6Osstt1x23HHHBV7H5u23307v3r3TvHnzdOzYMWeeeWbldSiKIp07d86OO+44x3ZTpkxJq1at8tOf/nSu+37//ffz+9//Pttss80cQdYsq622Wg499NBaj/2SSy6pHPu///3vJMmDDz6YzTffPM2bN0/r1q2z44475tVXX62xz7mtQVbb+bMwnwW1ueOOO/LDH/6w1vMySfr27Zubbrqpxsi7u+66K5MnT85uu+1W6zYffPBB9t9//7Rv3z7V1dVZZ511cvXVV9foM23atJx22mnZaKON0qpVqzRv3jybb755HnrooRr9FuZc+qaNGDEiDRs2rDX4a9myZSXcnZ8TTzwxW2+9dW6++ea88cYb8+z70ksvZb/99svKK6+cJk2apEOHDtl///3z8ccfz9H3gw8+yAEHHJCOHTumuro6Xbp0ySGHHJJp06Ylmfvn/CyXX3551llnnVRXV6djx4457LDD5phe/uabb2aXXXZJhw4d0qRJk6ywwgrZY489MmHChEqfYcOGZbPNNkvr1q3TokWLrLHGGvnFL34xz+P88Y9/nO9+97s12vr06TPH1O5//OMfqaqqyr333ltpGz9+fI4++ujK5/Gqq66aX/7yl4s0WvSZZ55J796906ZNmzRt2jRdunTJ/vvvP0e/rbbaKnfdddd8P/MBYHEyMguoUyNGjEjy5Vobs0yfPj29e/fOZpttlgsvvDDNmjVLURTZYYcd8tBDD+WAAw7IBhtskKFDh+b444/PBx98kIsvvrjGfh955JHcdNNNOfLII1NdXZ3LL78822yzTZ5++umsu+66SZJXXnklm2++eVq2bJmf//znadSoUX73u99liy22yCOPPJLu3bvX2Oehhx6atm3b5rTTTsukSZOy7bbb5o033sif//znXHzxxWnTpk2SpG3btrUe6+jRo7Pppptm8uTJOfLII7Psssvmuuuuyw477JBbbrklO++8c43+5513Xho0aJDjjjsuEyZMyPnnn5+99tor//jHP+b5nC7Icf34xz9O69atc8wxx6Rv377Zbrvt5rlg+I9//OMccsghGTJkSH784x/XuG/IkCFZaaWV0rNnz4V+nb6Ot956K3vuuWd++tOfZu+9986FF16YPn36ZPDgwfnFL35RCVEGDRqU3Xbbrca0z1deeSU9e/bM8ssvnxNPPDHNmzfPX/7yl+y000659dZb53gtajNlypSMHTs2yZcB3uOPP57rrrsue+65Z40wa26GDBmSTz/9ND/96U9TVVWV888/Pz/+8Y/z9ttvV0Zz7bLLLnnllVdyxBFHpHPnzhkzZkyGDRuWkSNHzndR+RkzZmSbbbbJJptskvPPPz/33XdfBg4cmOnTp+fMM89MVVVV9t5775x//vkZN25clllmmcq2d911VyZOnDjHyJnZ3XvvvZkxY8Y8+8zNNddckylTpuTggw9OdXV1lllmmTzwwAPZdttts/LKK+f000/P559/nt/+9rfp2bNnnnvuuUVeRH9BPgtq88EHH2TkyJFzhAiz23PPPXP66afn4YcfrgTzQ4YMyZZbbpl27drN0X/06NHZZJNNKiFb27Ztc++99+aAAw7IxIkTc/TRRyf5ciTT73//+/Tt2zcHHXRQPv300/zhD39I79698/TTT2eDDTaosd8FOZdqM3PmzIwbN65G29SpU/PFF19Uzu1ZWrVqNc99rbTSSpkxY0b++Mc/Zt99951rvwWxzz775P7778+wYcOy+uqrz7XfsGHD8vbbb6d///7p0KFDXnnllVx55ZV55ZVX8tRTT1VCyP/+97/ZeOONM378+Bx88MFZc80188EHH+SWW27J5MmTa4wa++rnfPJlUHrGGWekV69eOeSQQ/L666/niiuuyD//+c88/vjjadSoUaZNm5bevXtn6tSpOeKII9KhQ4d88MEH+dvf/pbx48enVatWeeWVV/KjH/0o66+/fs4888xUV1fnrbfeyuOPPz7P52PzzTfPnXfemYkTJ6Zly5YpiiKPP/54GjRokMceeyw77LBDkuSxxx5LgwYN0rNnzyTJ5MmT8/3vfz8ffPBBfvrTn2bFFVfME088kZNOOikffvhhLrnkkgV+TcaMGZOtt946bdu2zYknnpjWrVvn3XffzW233TZH34022igXX3xxXnnllXm+xwBgsSoAFsE111xTJCkeeOCB4qOPPiref//94sYbbyyWXXbZomnTpsV//vOfoiiKYt999y2SFCeeeGKN7e+4444iSXH22WfXaP/JT35SVFVVFW+99ValLUmRpHjmmWcqbe+9917RpEmTYuedd6607bTTTkXjxo2LESNGVNr++9//FksvvXTxve99b47aN9tss2L69Ok1Hv+CCy4okhTvvPPOHMe80korFfvuu2/l9tFHH10kKR577LFK26efflp06dKl6Ny5czFjxoyiKIrioYceKpIUa621VjF16tRK31//+tdFkuJf//rXnE/wbBb0uN55550iSXHBBRfMc3+z7LrrrkWTJk2KCRMmVNpee+21Iklx0kknFUWxcK/TV5+fgQMHFrV9zcx6/md/jldaaaUiSfHEE09U2oYOHVokKZo2bVq89957lfbf/e53RZLioYceqrRtueWWxXrrrVdMmTKl0jZz5sxi0003LVZbbbX5PhezzrGv/uy000419lkUX57TK620UuX2rOd92WWXLcaNG1dpv/POO4skxV133VUURVF88sknC/X6fPUxkxRHHHFEjePbfvvti8aNGxcfffRRURRF8frrrxdJiiuuuKLG9jvssEPRuXPnYubMmXN9jGOOOaZIUrzwwgs12qdOnVp89NFHlZ+xY8fOcewtW7YsxowZU2O7DTbYoGjXrl3x8ccfV9pefPHFokGDBkW/fv1qHNvsz+cstZ0/C/pZUJsHHnigxusxu+9///vFOuusUxRFUXTr1q044IADiqL48jVr3Lhxcd1111XexzfffHNluwMOOKBYbrnlajwnRVEUe+yxR9GqVati8uTJRVEUxfTp02u892ftu3379sX+++9faVvQc2luZm2/ID+zv39qM2rUqKJt27ZFkmLNNdcsfvaznxVDhgwpxo8fP0fffffdt2jevPlc9/X8888XSYpjjjlmno856/ma3Z///OciSfHoo49W2vr161c0aNCg+Oc//zlH/1nn+Nw+58eMGVM0bty42HrrrSuf0UVRFJdeemmRpLj66qtr1Dz76/1VF198cZGk8v5bUP/85z+LJMU999xTFEVRvPTSS0WSYtdddy26d+9e6bfDDjsUG264YeX2WWedVTRv3rx44403auzvxBNPLBo2bFiMHDmy0pakGDhwYOX2Vz93b7/99iJJrc/hVz3xxBNFkuKmm25aqOMEgG+SaYbA19KrV6+0bds2nTp1yh577JEWLVrk9ttvz/LLL1+j3yGHHFLj9j333JOGDRvmyCOPrNF+7LHHpiiKGtMqkqRHjx7ZaKONKrdXXHHF7Ljjjhk6dGhmzJiRGTNm5P77789OO+2UlVdeudJvueWWy5577pm///3vmThxYo19HnTQQWnYsOEiH/s999yTjTfeOJtttlmlrUWLFjn44IPz7rvvVqZazdK/f/8aIwY233zzJF9OHZubRTmuBbX33ntnypQpNf4SP2TIkCSpTDFc2Nfp61h77bXTo0ePyu1ZI+l++MMfZsUVV5yjfdbzNm7cuDz44IPZbbfd8umnn2bs2LEZO3ZsPv744/Tu3TtvvvlmPvjgg/k+/o477phhw4Zl2LBhufPOO3PSSSflvvvuy5577rlA02t23333fOc736nc/urr27Rp0zRu3DgPP/xwPvnkk/nurzazL+w/azTQtGnTKlemXH311dO9e/fccMMNlX7jxo3Lvffem7322muu0+uSVM6jr47ou+eee9K2bdvKz+xXAZxll112qTGC8cMPP8wLL7yQ/fbbr8YIsfXXXz9bbbVV7rnnnoU88v8zv8+CuZk1VW3216g2e+65Z2677bZMmzYtt9xySxo2bFjryL6iKHLrrbemT58+KYqict6NHTs2vXv3zoQJE/Lcc88lSRo2bFh5788aPTV9+vR069at0md28zuX5qZDhw6Vc3jWz9Zbb531119/jvauXbvOc1/t27fPiy++mJ/97Gf55JNPMnjw4Oy5555p165dzjrrrIWacjbrnPr000/n2a9p06aVf88aKTlrmuOs52nmzJm544470qdPn1qv1vrVc/yrn/MPPPBApk2blqOPPrrGBT0OOuigtGzZsjL1ulWrVkmSoUOHzvWKprPWJ7zzzjsXaprfhhtumBYtWlSmxz722GNZYYUV0q9fvzz33HOZPHlyiqLI3//+98prnyQ333xzNt9883znO9+pcb716tUrM2bMWODptrPX/re//S1ffPHFPPvOOhe/OroPAOqTMAv4Wi677LIMGzYsDz30UP79739X1vSZ3VJLLVVjrZIkee+999KxY8csvfTSNdrXWmutyv2zW2211eZ47NVXXz2TJ0/ORx99lI8++iiTJ0/OGmusMUe/tdZaKzNnzsz7779fo71Lly4LfqC1eO+99+b6eLPun93sgUzyf78gzCvYWJTjWlDbbrttlllmmUqAlSR//vOf07Vr16yzzjqVY1iY1+nr+OrzM+uXyU6dOtXaPut5e+utt1IURU499dQaoUvbtm0zcODAJF9OqZmfFVZYIb169UqvXr2yww475Nxzz83ZZ5+d2267LX/7298Wuv6vvr7V1dX55S9/mXvvvTft27fP9773vZx//vkZNWrUfPedJA0aNKgRaCapTNmafc2tfv365fHHH6+8NjfffHO++OKL7LPPPvPc/6zX+LPPPqvR3rNnzxrBSG2++l6a9dhzO2/Hjh1bmfK1sOb3WTA/8wthZq2JdO+99+aGG27Ij370oznO/+TL9+b48eNz5ZVXznHe9e/fP0nN8+66667L+uuvnyZNmmTZZZdN27Ztc/fdd9dYf2mWRfmsSL68IuOsc3jWz3LLLZfvfOc7c7TPL9RLvgzNr7jiinz44Yd5/fXX85vf/KYyZW9hrmg565yq7Xmc3bhx43LUUUelffv2adq0adq2bVs5t2Y9Tx999FEmTpy4wNPdFvTcbNy4cVZeeeXK/V26dMmAAQPy+9//Pm3atEnv3r1z2WWX1Xi9dt999/Ts2TMHHnhg2rdvnz322CN/+ctf5htsNWzYMD169Mhjjz2W5Mswa/PNN89mm22WGTNm5Kmnnsq///3vjBs3rkaY9eabb+a+++6b43ybdVXaBfmcm+X73/9+dtlll5xxxhlp06ZNdtxxx1xzzTWZOnXqHH1nvWfmFYYDwOJmzSzga9l4441r/ev47Kqrq2v8BXxJMfsogMVhbqPAFmaEQ11q1KhRdtttt1x11VUZPXp0Ro4cmTfffDPnn39+nex/br/4zG30zNyen/k9b7N+cTzuuOPmCFJnWXXVVedZ69xsueWWSZJHH300ffr0mWffBXl9jz766PTp0yd33HFHhg4dmlNPPTWDBg3Kgw8+mA033HCRavyqPfbYI8ccc0xuuOGG/OIXv8if/vSndOvWrdZgaXZrrrlmkuTll1+uMWpn9l+W//SnP9W67dd5Ly3sebKoZq3jN79AaLnllssWW2yRX/3qV3n88cfnegXDWefd3nvvPdc1pdZff/0kXz5v++23X3baaaccf/zxadeuXRo2bJhBgwZV1hmc3ZL2WVFVVZXVV189q6++erbffvusttpqueGGG3LggQcu0PYvv/xykvm/D3fbbbc88cQTOf7447PBBhukRYsWmTlzZrbZZptFWuA8+Xrn5q9+9avst99+ufPOO3P//ffnyCOPzKBBg/LUU09lhRVWSNOmTfPoo4/moYceyt1335377rsvN910U374wx/m/vvvn+fI38022yznnHNOpkyZksceeywnn3xyWrdunXXXXTePPfZY2rdvnyQ1wqyZM2dmq622ys9//vNa9zmv9ci+qqqqKrfcckueeuqp3HXXXRk6dGj233///OpXv8pTTz1VY4TmrPfMrHUkAWBJIMwC6sVKK62UBx54IJ9++mmNv9a/9tprlftn9+abb86xjzfeeCPNmjWrTG9q1qxZXn/99Tn6vfbaa2nQoMEcI3xqszB/eV5ppZXm+niz7v+62rZtWyfHNTd77bVXBg8enJtuuinvvPNOqqqq0rdv38r9C/s6zW7WyI/x48dXprQkdTuaK0lltFKjRo0qoUtdmT59epI5Ryt9HausskqOPfbYHHvssXnzzTezwQYb5Fe/+tVcg6JZZs6cmbfffrvGL6yzrg43+2LqyyyzTLbffvvccMMN2WuvvfL4448v0MLQ2267bRo2bFjZ7uuYdV7M7bxt06ZNmjdvnuTL8+SrV5FL5n6eLMhnQW1mhXWzrrQ6L3vuuWcOPPDAtG7dOtttt12tfdq2bZull146M2bMmO95d8stt2TllVfObbfdVuMzZtbIwTJZeeWV853vfCcffvjhAm/zxz/+MVVVVdlqq63m2ueTTz7J8OHDc8YZZ+S0006rtH/19W7btm1atmxZCcgW1uzn5uwjHadNm5Z33nlnjtdyvfXWy3rrrZdTTjklTzzxRHr27JnBgwfn7LPPTvLliMktt9wyW265ZS666KKce+65Ofnkk/PQQw/N87zYfPPNM23atPz5z3/OBx98UAmtvve971XCrNVXX70SaiVffnZ89tlndfo5t8kmm2STTTbJOeeckyFDhmSvvfbKjTfeWCOonPWemTUiFwCWBEveUAngf8J2222XGTNm5NJLL63RfvHFF6eqqirbbrttjfYnn3yyxtoy77//fu68885svfXWadiwYRo2bJitt946d955Z40pV6NHj86QIUOy2WabpWXLlvOta9Yv2LX9cl3bMTz99NN58sknK22TJk3KlVdemc6dO2fttdee7z7mp66Oa2569uyZzp07509/+lNuuummfP/7368xJXRhX6fZrbLKKklSYx2XSZMm5brrrlvkemvTrl27bLHFFvnd735X6y/YCzL1bG7uuuuuJJnv+kILYvLkyZkyZUqNtlVWWSVLL710rVN7ajP761AURS699NI0atSoMoJsln322Sf//ve/c/zxx6dhw4bZY4895rvvFVdcMfvvv3/uvffeOV7v2R9zQSy33HLZYIMNct1119V4L7388su5//77awREq6yySiZMmJCXXnqp0vbhhx/m9ttvr3Xf8/ssmJvll18+nTp1yjPPPDPf+n/yk59k4MCBufzyy2uscze7hg0bZpdddsmtt95aa7Ay+3k3q67Zn79//OMfNT47vinXXnttHn744YXe7h//+EetU0GffvrpfPzxx/Md6TfLeeedl/vvvz+77757rVNEZ6ntOUoyRxDboEGD7LTTTrnrrrtqfS3nd4726tUrjRs3zm9+85saff/whz9kwoQJ2X777ZN8uYbcrDB7lvXWWy8NGjSovF+/euXIJJUrU87vPd29e/c0atQov/zlL7PMMstUpnZvvvnmeeqpp/LII4/UGJWVfDly7cknn8zQoUPn2N/48ePnqHdePvnkkzmeq7nV/uyzz6ZVq1aVGgFgSWBkFlAv+vTpkx/84Ac5+eST8+6776Zr1665//77c+edd+boo4+uBCGzrLvuuundu3eOPPLIVFdX5/LLL0+SnHHGGZU+Z599doYNG5bNNtsshx56aJZaaqn87ne/y9SpUxd46tyshaVPPvnk7LHHHmnUqFH69OlTCblmd+KJJ+bPf/5ztt122xx55JFZZpllct111+Wdd97JrbfeWmdTK+viuOamqqoqe+65Z84999wkyZlnnlnj/oV9nWa39dZbZ8UVV8wBBxxQCVWuvvrqtG3bNiNHjvxadX/VZZddls022yzrrbdeDjrooKy88soZPXp0nnzyyfznP//Jiy++ON99vPHGG5XRUZMnT85TTz2V6667Lquuuup815taEG+88Ua23HLL7Lbbbll77bWz1FJL5fbbb8/o0aMXKGxq0qRJ7rvvvuy7777p3r177r333tx99935xS9+MceIpO233z7LLrtsbr755my77bZp167dAtV4ySWX5J133skRRxyRG2+8MX369Em7du0yduzYPP7447nrrrsWOMS44IILsu2226ZHjx454IAD8vnnn+e3v/1tWrVqldNPP73Sb4899sgJJ5yQnXfeOUceeWQmT56cK664Iquvvnqti6MvyGfB3Oy44465/fbbUxTFPEdhfrXGuTnvvPPy0EMPpXv37jnooIOy9tprZ9y4cXnuuefywAMPVMKOH/3oR7ntttuy8847Z/vtt88777yTwYMHZ+21167TUX+TJk2aawj4VVtttVWNUT9f9cc//jE33HBDdt5552y00UZp3LhxXn311Vx99dVp0qRJfvGLX9ToP3369Mr7Z8qUKXnvvffy17/+NS+99FJ+8IMf5Morr5xnPS1btqysI/fFF19k+eWXz/3331/rSLpzzz03999/f77//e/n4IMPzlprrZUPP/wwN998c/7+97/XGAn6VW3bts1JJ52UM844I9tss0122GGHvP7667n88svz//7f/8vee++dJHnwwQdz+OGHZ9ddd83qq6+e6dOn549//GMlxEy+/Lx89NFHs/3222ellVbKmDFjcvnll2eFFVaocWGQ2jRr1iwbbbRRnnrqqfTp06dyPn7ve9/LpEmTMmnSpDnCrOOPPz5//etf86Mf/Sj77bdfNtpoo0yaNCn/+te/csstt+Tdd99d4KmA1113XS6//PLsvPPOWWWVVfLpp5/mqquuSsuWLecYjThs2LAaNQLAEmFxXjoR+PaYdZnv+V3We16XbP/000+LY445pujYsWPRqFGjYrXVVisuuOCCyqXVZ0lSHHbYYcWf/vSnYrXVViuqq6uLDTfcsNZLyz/33HNF7969ixYtWhTNmjUrfvCDHxRPPPHEQtV+1llnFcsvv3zRoEGDGpcyX2mllYp99923Rt8RI0YUP/nJT4rWrVsXTZo0KTbeeOPib3/7W40+Dz30UK2XeH/nnXeKJMU111xTax0Le1yz9nfBBRfMd3+ze+WVV4okRXV1dfHJJ5/Mcf+Cvk61PT/PPvts0b1796Jx48bFiiuuWFx00UVzXCJ+1rbbb7/9HI8967VfkOMcMWJE0a9fv6JDhw5Fo0aNiuWXX7740Y9+VNxyyy3zfQ6S1Php2LBhscIKKxQHH3xwMXr06Bp9991332KllVaabz2z9jtw4MCiKIpi7NixxWGHHVasueaaRfPmzYtWrVoV3bt3L/7yl7/Mt75Z76MRI0YUW2+9ddGsWbOiffv2xcCBA4sZM2bUus2hhx5aJCmGDBky3/3Pbvr06cU111xT/PCHPyyWWWaZYqmlliratGlTbLnllsXgwYOLzz//fIGOvSiK4oEHHih69uxZNG3atGjZsmXRp0+f4t///vcc/e6///5i3XXXLRo3blysscYaxZ/+9Kdi4MCBxVf/m7IwnwW1ee6554okxWOPPVaj/fvf/36xzjrrzHPbub2PR48eXRx22GFFp06dikaNGhUdOnQottxyy+LKK6+s9Jk5c2Zx7rnnFiuttFKl5r/97W+LfC7NzaztF+Rnfs/ZSy+9VBx//PHFd7/73cp5sNxyyxW77rpr8dxzz9Xou++++9bYd7NmzYrOnTsXu+yyS3HLLbfM9Rz9qv/85z/FzjvvXLRu3bpo1apVseuuuxb//e9/az329957r+jXr1/Rtm3borq6ulh55ZWLww47rJg6dWpRFPP/nL/00kuLNddcs2jUqFHRvn374pBDDqnx+ff2228X+++/f7HKKqsUTZo0KZZZZpniBz/4QfHAAw9U+gwfPrzYcccdi44dOxaNGzcuOnbsWPTt27d44403Fuh4jz/++CJJ8ctf/rJG+6qrrlokKUaMGDHHNp9++mlx0kknFauuumrRuHHjok2bNsWmm25aXHjhhcW0adMq/b76nH31c/e5554r+vbtW6y44opFdXV10a5du+JHP/pR8cwzz9R4vFdffbVIUuO4AWBJUFUU9bSaKMACqqqqymGHHTbXqU/AnI455pj84Q9/yKhRo9KsWbP6LqdO1MVnwZZbbpmOHTvmj3/8Yx1WBt9ORx99dB599NE8++yzRmYBsESxZhYAfMtMmTIlf/rTn7LLLrt8a4KsunLuuefmpptuqvMLEcC3zccff5zf//73OfvsswVZACxxrJkFAN8SY8aMyQMPPJBbbrklH3/8cY466qj6LmmJ071790ybNq2+y4Al3rLLLluna7oBQF0SZgHAt8S///3v7LXXXmnXrl1+85vfVK5OBgAA3yb1umbWo48+mgsuuCDPPvts5TLcO+200zy3efjhhzNgwIC88sor6dSpU0455ZTst99+i6VeAAAAAOpXva6ZNWnSpHTt2jWXXXbZAvV/5513sv322+cHP/hBXnjhhRx99NE58MADM3To0G+4UgAAAACWBEvM1QyrqqrmOzLrhBNOyN13352XX3650rbHHntk/Pjxue+++xZDlQAAAADUp1KtmfXkk0+mV69eNdp69+6do48+eq7bTJ06NVOnTq3cnjlzZsaNG5dll13WlVkAAAD4xhVFkU8//TQdO3ZMgwb1OkEKvhVKFWaNGjUq7du3r9HWvn37TJw4MZ9//nmaNm06xzaDBg3KGWecsbhKBAAAgFq9//77WWGFFeq7DCi9UoVZi+Kkk07KgAEDKrcnTJiQFVdcMe+//35atmxZj5VRl3Zs1a++S2AhfZrxmZRPF3q75lk6S6d13RfEN+bOCdfXdwnAPPgOLR/fof87fId+e0ycODGdOnXK0ksvXd+lwLdCqcKsDh06ZPTo0TXaRo8enZYtW9Y6KitJqqurU11dPUd7y5YthVnfIktVNarvElhI30nbfCdt67sMFgOftbBk8x1aPr5D/3f4Dv32sdQN1I1STdbt0aNHhg8fXqNt2LBh6dGjRz1VBAAAAMDiVK9h1meffZYXXnghL7zwQpLknXfeyQsvvJCRI0cm+XKKYL9+/zf0/Wc/+1nefvvt/PznP89rr72Wyy+/PH/5y19yzDHH1Ef5AAAAACxm9RpmPfPMM9lwww2z4YYbJkkGDBiQDTfcMKeddlqS5MMPP6wEW0nSpUuX3H333Rk2bFi6du2aX/3qV/n973+f3r1710v9AAAAACxe9bpm1hZbbJGiKOZ6/7XXXlvrNs8///w3WBUAAACwMGbMmJEvvviivsugxBo1apSGDRsuUN9SLQAPAAAALDmKosioUaMyfvz4+i6Fb4HWrVunQ4cO871YgjALAAAAWCSzgqx27dqlWbNmrtjIIimKIpMnT86YMWOSJMstt9w8+wuzAAAAgIU2Y8aMSpC17LLL1nc5lFzTpk2TJGPGjEm7du3mOeWwXheABwAAAMpp1hpZzZo1q+dK+LaYdS7Nb/01YRYAAACwyEwtpK4s6LkkzAIAAACgNIRZAAAAwBKnc+fOueSSS+q7jG+1ffbZJ+eee+43/jhjx45Nu3bt8p///KdO9ifMAgAAAOpMnz59ss0229R632OPPZaqqqq89NJLi7mqurXFFlukqqoqVVVVadKkSVZfffUMGjQoRVHUd2kL7MUXX8w999yTI488ss72OWnSpOyzzz7Zdttt06tXr9xyyy1JkjZt2qRfv34ZOHBgnTyOMAsAAACoMwcccECGDRtW6yica665Jt26dcv6669fD5XVrYMOOigffvhhXn/99Zx00kk57bTTMnjw4Poua4H99re/za677poWLVrU2T6bN2+es88+O1OnTs1zzz2XO++8s3Jf//79c8MNN2TcuHFf+3GEWQAAAECd+dGPfpS2bdvm2muvrdH+2Wef5eabb84BBxyQJLn11luzzjrrpLq6Op07d86vfvWrue7z3XffTVVVVV544YVK2/jx41NVVZWHH344SfLwww+nqqoqQ4cOzYYbbpimTZvmhz/8YcaMGZN77703a621Vlq2bJk999wzkydPruxn5syZGTRoULp06ZKmTZuma9eulRFF89KsWbN06NAhK620Uvr375/1118/w4YNq9w/YsSI7Ljjjmnfvn1atGiR//f//l8eeOCBGvvo3Llzzj333Oy///5Zeumls+KKK+bKK6+s0eeJJ57IBhtskCZNmqRbt26544475nguXn755Wy77bZp0aJF2rdvn3322Sdjx46da+0zZszILbfckj59+sxRz1lnnZW+ffumefPmWX755XPZZZdV7n/44YfTuHHjPPbYY5W2888/P+3atcvo0aOTJCuttFIefPDBDBkyJLvvvnul3zrrrJOOHTvm9ttvn+9zOz/CLAAAAKDOLLXUUunXr1+uvfbaGtPubr755syYMSN9+/bNs88+m9122y177LFH/vWvf+X000/PqaeeOkcAtihOP/30XHrppXniiSfy/vvvZ7fddssll1ySIUOG5O67787999+f3/72t5X+gwYNyvXXX5/BgwfnlVdeyTHHHJO99947jzzyyAI9XlEUeeyxx/Laa6+lcePGlfbPPvss2223XYYPH57nn38+22yzTfr06ZORI0fW2P5Xv/pVunXrlueffz6HHnpoDjnkkLz++utJkokTJ6ZPnz5Zb7318txzz+Wss87KCSecUGP78ePH54c//GE23HDDPPPMM7nvvvsyevTo7LbbbnOt+aWXXsqECRPSrVu3Oe674IIL0rVr1zz//PM58cQTc9RRR1VCui222CJHH3109tlnn0yYMCHPP/98Tj311Pz+979P+/btM2XKlMp+GjRokFNOOaXGvjfeeOMaQdiiWupr7wEAAABgNvvvv38uuOCCPPLII9liiy2SfDnFcJdddkmrVq1y0UUXZcstt8ypp56aJFl99dXz73//OxdccEH222+/r/XYZ599dnr27JnkyymPJ510UkaMGJGVV145SfKTn/wkDz30UE444YRMnTo15557bh544IH06NEjSbLyyivn73//e373u9/l+9///lwf5/LLL8/vf//7TJs2LV988UWaNGlSY/2prl27pmvXrpXbZ511Vm6//fb89a9/zeGHH15p32677XLooYcmSU444YRcfPHFeeihh7LGGmtkyJAhqaqqylVXXZUmTZpk7bXXzgcffJCDDjqosv2ll16aDTfcsMZC7ldffXU6deqUN954I6uvvvoctb/33ntp2LBh2rVrN8d9PXv2zIknnpjky9fl8ccfz8UXX5ytttqq8vwOGzYsBx98cF5++eXsu+++2WGHHZJ8GZIdddRRadSoUcaNGzfHGlkdO3bM888/P9fndEEJswAAAIA6teaaa2bTTTfN1VdfnS222CJvvfVWHnvssZx55plJkldffTU77rhjjW169uyZSy65JDNmzEjDhg0X+bFnX4+rffv2adasWSXImtX29NNPJ0neeuutTJ48uRLUzDJt2rRsuOGG83ycvfbaKyeffHI++eSTDBw4MJtuumk23XTTyv2fffZZTj/99Nx999358MMPM3369Hz++edzjMyavd6qqqp06NAhY8aMSZK8/vrrWX/99dOkSZNKn4033rjG9i+++GIeeuihWte+GjFiRK1h1ueff57q6upUVVXNcd+sUG/227NfVbJx48a54YYbsv7662ellVbKxRdfXKO2J598co59ztK0adMaUzwXlTALAAAAqHMHHHBAjjjiiFx22WW55pprssoqq8xzpNO8NGjw5SpJs09b/OKLL2rt26hRo8q/q6qqatye1TZz5swkXwZOSXL33Xdn+eWXr9Gvurp6njW1atUqq666apLkL3/5S1ZdddVssskm6dWrV5LkuOOOy7Bhw3LhhRdm1VVXTdOmTfOTn/wk06ZNm2u9X61vQXz22Wfp06dPfvnLX85x33LLLVfrNm3atMnkyZMzbdq0GlMjF9QTTzyRJBk3blzGjRuX5s2bL9B248aNS9u2bRf68b7KmlkAAABAndttt93SoEGDDBkyJNdff33233//ykigtdZaK48//niN/o8//nhWX331WkdlzQpAPvzww0rb7AugL6q111471dXVGTlyZFZdddUaP506dVrg/bRo0SJHHXVUjjvuuErg9vjjj2e//fbLzjvvnPXWWy8dOnTIu+++u1D1rbHGGvnXv/6VqVOnVtr++c9/1ujz3e9+N6+88ko6d+48xzHMLWTaYIMNkiT//ve/57jvqaeemuP2WmutVbk9YsSIHHPMMbnqqqvSvXv37Lvvvgscvr388svzHfG2IIRZAAAAQJ1r0aJFdt9995x00kn58MMPa6yFdeyxx2b48OE566yz8sYbb+S6667LpZdemuOOO67WfTVt2jSbbLJJzjvvvLz66qt55JFH5lhcfFEsvfTSOe6443LMMcfkuuuuy4gRI/Lcc8/lt7/9ba677rqF2tdPf/rTvPHGG7n11luTJKuttlpuu+22vPDCC3nxxRez5557LtSIqySVbQ4++OC8+uqrGTp0aC688MIkqQSDhx12WMaNG5e+ffvmn//8Z0aMGJGhQ4emf//+mTFjRq37bdu2bb773e/m73//+xz3Pf744zn//PPzxhtv5LLLLsvNN9+co446KsmXV0Hce++907t37/Tv3z/XXHNNXnrppXleiXKWyZMn59lnn83WW2+9UM9BbYRZAAAAwDfigAMOyCeffJLevXunY8eOlfbvfve7+ctf/pIbb7wx6667bk477bSceeaZ81z8/eqrr8706dOz0UYb5eijj87ZZ59dJzWeddZZOfXUUzNo0KCstdZa2WabbXL33XenS5cuC7WfZZZZJv369cvpp5+emTNn5qKLLsp3vvOdbLrppunTp0969+6d7373uwu1z5YtW+auu+7KCy+8kA022CAnn3xyTjvttCSprKPVsWPHPP7445kxY0a23nrrrLfeejn66KPTunXryvTM2hx44IG54YYb5mg/9thj88wzz2TDDTfM2WefnYsuuii9e/dOkpxzzjl577338rvf/S7Jl9MYr7zyypxyyil58cUX53ksd955Z1ZcccVsvvnmC/Uc1KaqmH3C6f+AiRMnplWrVpkwYUJatmxZ3+VQR7ZqsGt9lwDMxbCZN9d3CcA8+A6FJZfv0G+Pb+vvoVOmTMk777yTLl261FignG/WDTfckP79+2fChAlp2rTpIu/n888/zxprrJGbbrqpsuh7586dc/TRR+foo4+uo2r/zyabbJIjjzwye+6551z7LOg5ZQF4AAAAgCXU9ddfn5VXXjnLL798XnzxxZxwwgnZbbfdvlaQlXw5dfP666/P2LFj66jSuRs7dmx+/OMfp2/fvnWyP2EWAAAAwBJq1KhROe200zJq1Kgst9xy2XXXXXPOOefUyb632GKLOtnP/LRp0yY///nP62x/wiwAAACAJdTPf/7zOg2C5mVhr7ZYXywADwAAAEBpCLMAAAAAKA1hFgAAAAClIcwCAAAAoDSEWQAAAACUhjALAAAAgNIQZgEAAABQGkvVdwEAAAAAX9dWDXZdrI83bObNC9X/0UcfzQUXXJBnn302H374YW6//fbstNNOC/24RVFk4MCBueqqqzJ+/Pj07NkzV1xxRVZbbbV5bnfZZZflggsuyKhRo9K1a9f89re/zcYbb7zQj78kMDILAAAA4Bs2adKkdO3aNZdddtnX2s/555+f3/zmNxk8eHD+8Y9/pHnz5undu3emTJky121uuummDBgwIAMHDsxzzz2Xrl27pnfv3hkzZszXqqW+CLMAAAAAvmHbbrttzj777Oy8886LvI+iKHLJJZfklFNOyY477pj1118/119/ff773//mjjvumOt2F110UQ466KD0798/a6+9dgYPHpxmzZrl6quvXuRa6pMwCwAAAGAJcPrpp6dz585zvf+dd97JqFGj0qtXr0pbq1at0r179zz55JO1bjNt2rQ8++yzNbZp0KBBevXqNddtlnTCLAAAAIAlQJs2bbLKKqvM9f5Ro0YlSdq3b1+jvX379pX7vmrs2LGZMWPGQm2zpBNmAQAAACwBDj/88AwfPry+y1jiCbMAAAAASqBDhw5JktGjR9doHz16dOW+r2rTpk0aNmy4UNss6YRZAAAAACXQpUuXdOjQocborYkTJ+Yf//hHevToUes2jRs3zkYbbVRjm5kzZ2b48OFz3WZJJ8wCAAAA+IZ99tlneeGFF/LCCy8k+XIx9xdeeCEjR46s9Ln00kuz5ZZbznUfVVVVOfroo3P22Wfnr3/9a/71r3+lX79+6dixY3baaadKvy233DKXXnpp5faAAQNy1VVX5brrrsurr76aQw45JJMmTUr//v3r/DgXh6XquwAAAACAb7tnnnkmP/jBDyq3BwwYkCTZd999c+211yb5crH2ESNGzHM/P//5zzNp0qQcfPDBGT9+fDbbbLPcd999adKkSaXPiBEjMnbs2Mrt3XffPR999FFOO+20jBo1KhtssEHuu+++ORaFL4uqoiiK+i5icZo4cWJatWqVCRMmpGXLlvVdDnVkqwa71ncJwFwMm3lzfZcAzIPvUFhy+Q799vi2/h46ZcqUvPPOO+nSpUuNIAUW1YKeU6YZAgAAAFAawiwAAAAASkOYBQAAAEBpCLMAAAAAKA1hFgAAALDI/seuK8c3aEHPJWEWAAAAsNAaNWqUJJk8eXI9V8K3xaxzada5NTdLLY5iAAAAgG+Xhg0bpnXr1hkzZkySpFmz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JOnbt2/22muvNG3atE4LBAAAAIBZFinMSpJmzZrloIMOqstaAAAAAGCeFjjM+utf/5ptt902jRo1yl//+td59t1hhx2+dmEAAAAA8FULHGbttNNOGTVqVNq1a5eddtpprv2qqqoyY8aMuqgNAAAAAGpY4DBr5syZtf4bAAAAABaXBouy0fXXX5+pU6fO0T5t2rRcf/31X7soAAAAAKjNIoVZ/fv3z4QJE+Zo//TTT9O/f/+vXRQAAAAA1GaRwqyiKFJVVTVH+3/+85+0atXqaxcFAAAAALVZ4DWzkmTDDTdMVVVVqqqqsuWWW2appf5v8xkzZuSdd97JNttsU+dFAgAAAECykGHWrKsYvvDCC+ndu3datGhRua9x48bp3LlzdtlllzotEAAAAABmWagwa+DAgZkxY0Y6d+6crbfeOsstt9w3VRcAAAAAzGGh18xq2LBhfvrTn2bKlCnfRD0AAAAAMFeLtAD8uuuum7fffruuawEAAACAeVqkMOvss8/Occcdl7/97W/58MMPM3HixBo/AAAAAPBNWKg1s2bZbrvtkiQ77LBDqqqqKu1FUaSqqiozZsyom+oAAAAAYDaLFGY99NBDdV0HAAAAAMzXIoVZ3//+9+u6DgAAAACYr0UKs5Jk/Pjx+cMf/pBXX301SbLOOutk//33T6tWreqsOAAAAACY3SItAP/MM89klVVWycUXX5xx48Zl3Lhxueiii7LKKqvkueeeq+saAQAAACDJIo7MOuaYY7LDDjvkqquuylJLfbmL6dOn58ADD8zRRx+dRx99tE6LBAAAAIBkEcOsZ555pkaQlSRLLbVUfv7zn6dbt251VhwAAAAAzG6Rphm2bNkyI0eOnKP9/fffz9JLL/21iwIAAACA2ixSmLX77rvngAMOyE033ZT3338/77//fm688cYceOCB6du3b13XCAAAAABJFnGa4YUXXpiqqqr069cv06dPT5I0atQohxxySM4777w6LRAAAAAAZlmkMKtx48b59a9/nUGDBmXEiBFJklVWWSXNmjWr0+IAAAAAYHaLFGbN0qxZs7Ru3brybwAAAAD4Ji3SmlnTp0/PqaeemlatWqVz587p3LlzWrVqlVNOOSVffPFFXdcIAAAAAEkWcWTWEUcckdtuuy3nn39+evTokSR58sknc/rpp+fjjz/OFVdcUadFAgAAAECyiGHWkCFDcuONN2bbbbettK2//vrp1KlT+vbtK8wCAAAA4BuxSNMMq6ur07lz5znau3TpksaNG3/dmgAAAACgVosUZh1++OE566yzMnXq1Erb1KlTc8455+Twww+vs+IAAAAAYHaLNM3w+eefz/Dhw7PCCiuka9euSZIXX3wx06ZNy5Zbbpkf//jHlb633XZb3VQKAAAAwP+8RQqzWrdunV122aVGW6dOneqkIAAAAACYm0UKs6655pq6rgMAAAAA5muRwqxZPvroo7z++utJkjXWWCNt27atk6IAAAAAoDaLtAD8pEmTsv/++2e55ZbL9773vXzve99Lx44dc8ABB2Ty5Ml1XSMAAAAAJFnEMGvAgAF55JFHctddd2X8+PEZP3587rzzzjzyyCM59thj67pGAAAAAEiyiNMMb7311txyyy3ZYostKm3bbbddmjZtmt122y1XXHFFXdUHAAAAABWLNDJr8uTJad++/Rzt7dq1M80QAAAAgG/MIoVZPXr0yMCBAzNlypRK2+eff54zzjgjPXr0qLPiAAAAAGB2izTN8JJLLsk222yTFVZYIV27dk2SvPjii2nSpEmGDh1apwUCAAAAwCyLFGatt956efPNN3PDDTfktddeS5L07ds3e+21V5o2bVqnBQIAAADALAsdZn3xxRdZc80187e//S0HHXTQN1ETAAAAANRqodfMatSoUY21sgAAAABgcVmkBeAPO+yw/PKXv8z06dPruh4AAAAAmKtFWjPrn//8Z4YPH577778/6623Xpo3b17j/ttuu61OigMAAACA2S1SmNW6devssssudV0LAAAAAMzTQoVZM2fOzAUXXJA33ngj06ZNyw9/+MOcfvrprmAIAAAAwGKxUGtmnXPOOfnFL36RFi1aZPnll89vfvObHHbYYd9UbQAAAABQw0KFWddff30uv/zyDB06NHfccUfuuuuu3HDDDZk5c+Y3VR8AAAAAVCxUmDVy5Mhst912ldu9evVKVVVV/vvf/9Z5YQAAAADwVQsVZk2fPj1NmjSp0daoUaN88cUXdVoUAAAAANRmoRaAL4oi++23X6qrqyttU6ZMyc9+9rM0b9680nbbbbfVXYUAAAAA8P9bqDBr3333naNt7733rrNiAAAAAGBeFirMuuaaa76pOgAAAABgvhZqzSwAAAAAqE/CLAAAAABKQ5gFAAAAQGkI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wELwHQpLrqIo8umnn6Zjx471XQp8K9RrmNWmTZs0bNgwo0ePrtE+evTodOjQodZtOnTosFD9q6urU11dXaOtdevWi140sFi0bNnSf8QBYBH4DoUlkxFZUHfq9WqGjRs3zkYbbZThw4dX2mbOnJnhw4enR48etW7To0ePGv2TZNiwYXPtDwAAAMC3R71PMxwwYED23XffdOvWLRtvvHEuueSSTJo0Kf3790+S9OvXL8svv3wGDRqUJDnqqKPy/e9/P7/61a+y/fbb58Ybb8wzzzyTK6+8sj4PAwAAAIDFoN7DrN133z0fffRRTjvttIwaNSobbLBB7rvvvsoi7yNHjkyDBv83gGzTTTfNkCFDcsopp+QXv/hFVltttdxxxx1Zd9116+sQgDpUXV2dgQMHzjE9GACYN9+hAPyvqCpcGxQAAACAkqjXNbMAAAAAYGEIswAAAAAoDWEWAAAAAKUhzAIAAACgNIRZAAAAAJSGMAsAAACA0hBmAfXunnvuydChQ+doHzp0aO699956qAgAAIAllTALqHcnnnhiZsyYMUd7URQ58cQT66EiACiHa665JjfffPMc7TfffHOuu+66eqgIAL55wiyg3r355ptZe+2152hfc80189Zbb9VDRQBQDoMGDUqbNm3maG/Xrl3OPffceqgIAL55wiyg3rVq1Spvv/32HO1vvfVWmjdvXg8VAUA5jBw5Ml26dJmjfaWVVsrIkSProSIA+OYJs4B6t+OOO+boo4/OiBEjKm1vvfVWjj322Oywww71WBkALNnatWuXl156aY72F198Mcsuu2w9VAQA3zxhFlDvzj///DRv3jxrrrlmunTpki5dumTNNdfMsssumwsvvLC+ywOAJVbfvn1z5JFH5qGHHsqMGTMyY8aMPPjggznqqKOyxx571Hd5APCNqCqKoqjvIgCKosgDDzyQF154IU2bNs3666+f733ve/VdFgAs0aZNm5Z99tknN998c5ZaaqkkyYwZM7Lvvvtm8ODBady4cT1XCAB1T5gFLBGGDx+e4cOHZ8yYMZk5c2aN+66++up6qgoAyuHNN9/M888/X/mD0EorrVTfJQHAN2ap+i4A4IwzzsiZZ56Zbt26ZbnllktVVVV9lwQApfGHP/whF198cd58880kyWqrrZajjz46Bx54YD1XBgDfDGEWUO8GDx6ca6+9Nvvss099lwIApXLaaafloosuyhFHHJEePXokSZ588skcc8wxGTlyZM4888x6rhAA6p5phkC9W3bZZfP0009nlVVWqe9SAKBU2rZtm9/85jfp27dvjfY///nPOeKIIzJ27Nh6qgwAvjmuZgjUuwMPPDBDhgyp7zIAoHS++OKLdOvWbY72jTbaKNOnT6+HigDgm2eaIVDvpkyZkiuvvDIPPPBA1l9//TRq1KjG/RdddFE9VQYAS7Z99tknV1xxxRzflVdeeWX22muveqoKAL5ZphkC9e4HP/jBXO+rqqrKgw8+uBirAYDyOOKII3L99denU6dO2WSTTZIk//jHPzJy5Mj069evxh+I/HEIgG8LYRYAAJTUvP4gNDt/HALg20SYBQAAAEBpWAAeAAAAgNIQZgEAAABQGsIsAAAAAEpDmAUAAABAaQizAOB/wKhRo3LUUUdl1VVXTZMmTdK+ffv07NkzV1xxRSZPnlzf5QEAwAJbqr4LAAC+WW+//XZ69uyZ1q1b59xzz816662X6urq/Otf/8qVV16Z5ZdfPjvssMMc233xxRdp1KhRPVQMAABzZ2QWAHzLHXrooVlqqaXyzDPPZLfddstaa62VlVdeOTvuuGPuvvvu9OnTJ0lSVVWVK664IjvssEOaN2+ec845J0lyxRVXZJVVVknjxo2zxhpr5I9//GNl3++++26qqqrywgsvVNrGjx+fqqqqPPzww0mShx9+OFVVVbn77ruz/vrrp0mTJtlkk03y8ssvL7bnAACAbw9hFgB8i3388ce5//77c9hhh6V58+a19qmqqqr8+/TTT8/OO++cf/3rX9l///1z++2356ijjsqxxx6bl19+OT/96U/Tv3//PPTQQwtdy/HHH59f/epX+ec//5m2bdumT58++eKLLxb52AAA+N8kzAKAb7G33norRVFkjTXWqNHepk2btGjRIi1atMgJJ5xQad9zzz3Tv3//rLzyyllxxRVz4YUXZr/99suhhx6a1VdfPQMGDMiPf/zjXHjhhQtdy8CBA7PVVltlvfXWy3XXXZfRo0fn9ttv/9rHCADA/xZhFgD8D3r66afzwgsvZJ111snUqVMr7d26davR79VXX03Pnj1rtPXs2TOvvvrqQj9mjx49Kv9eZpllssYaayzSfgAA+N9mAXgA+BZbddVVU1VVlddff71G+8orr5wkadq0aY32uU1FnJsGDb78u1hRFJU2UwcBAPgmGZkFAN9iyy67bLbaaqtceumlmTRp0kJvv9Zaa+Xxxx+v0fb4449n7bXXTpK0bds2SfLhhx9W7p99MfjZPfXUU5V/f/LJJ3njjTey1lprLXRNAAD8bzMyCwC+5S6//PL07Nkz3bp1y+mnn571118/DRo0yD//+c+89tpr2Wijjea67fHHH5/ddtstG264YXr16pW77rort912Wx544IEkX47s2mSTTXLeeeelS5cuGTNmTE455ZRa93XmmWdm2WWXTfv27XPyySenTZs22Wmnnb6JQwYA4FtMmAUA33KrrLJKnn/++Zx77rk56aST8p///CfV1dVZe+21c9xxx+XQQw+d67Y77bRTfv3rX+fCCy/MUUcdlS5duuSaa67JFltsUelz9dVX54ADDshGG22UNdZYI+eff3623nrrOfZ13nnn5aijjsqbb76ZDTbYIHfddVcaN278TRwyAADfYlXF7ItcAADUsYcffjg/+MEP8sknn6R169b1XQ4AACVnzSwAAAAASkOYBQAAAEBpmGYIAAAAQGkYmQUAAABAaQizAAAAACgNYRYAAAAApSHMAgAAAKA0hFkAAAAAlIYwCwAAAIDSEGYBAAAAUBrCLAAAAABKQ5gFAAAAQGn8f92/rLjpCkFDAAAAAElFTkSuQmCC",
149
+ "text/plain": [
150
+ "<Figure size 1200x800 with 1 Axes>"
151
+ ]
152
+ },
153
+ "metadata": {},
154
+ "output_type": "display_data"
155
+ }
156
+ ],
157
+ "source": [
158
+ "import spacr\n",
159
+ "import os\n",
160
+ "from scipy.stats import chi2_contingency\n",
161
+ "import pandas as pd\n",
162
+ "import matplotlib.pyplot as plt\n",
163
+ "%matplotlib inline\n",
164
+ "\n",
165
+ "def analyze_class_proportion(settings):\n",
166
+ " \n",
167
+ " from spacr.utils import annotate_conditions, save_settings\n",
168
+ " from spacr.io import _read_and_merge_data\n",
169
+ " #from spacr.settings import set_analyze_class_proportion_defaults\n",
170
+ " \n",
171
+ " def _plot_proportion_stacked_bars(settings, df, group_column, bin_column, prc_column='prc', level='object'):\n",
172
+ " # Always calculate chi-squared on raw data\n",
173
+ " raw_counts = df.groupby([group_column, bin_column]).size().unstack(fill_value=0)\n",
174
+ " chi2, p, dof, expected = chi2_contingency(raw_counts)\n",
175
+ " print(f\"Chi-squared test statistic (raw data): {chi2:.4f}\")\n",
176
+ " print(f\"p-value (raw data): {p:.4e}\")\n",
177
+ "\n",
178
+ " # Plot based on level setting\n",
179
+ " if level == 'well':\n",
180
+ " # Aggregate by well for mean ± SD visualization\n",
181
+ " well_proportions = (\n",
182
+ " df.groupby([group_column, prc_column, bin_column])\n",
183
+ " .size()\n",
184
+ " .groupby(level=[0, 1])\n",
185
+ " .apply(lambda x: x / x.sum())\n",
186
+ " .unstack(fill_value=0)\n",
187
+ " )\n",
188
+ " mean_proportions = well_proportions.groupby(group_column).mean()\n",
189
+ " std_proportions = well_proportions.groupby(group_column).std()\n",
190
+ "\n",
191
+ " ax = mean_proportions.plot(\n",
192
+ " kind='bar', stacked=True, yerr=std_proportions, capsize=5, colormap='viridis', figsize=(12, 8)\n",
193
+ " )\n",
194
+ " plt.title('Proportion of Volume Bins by Group (Mean ± SD across wells)')\n",
195
+ " else:\n",
196
+ " # Object-level plotting without aggregation\n",
197
+ " group_counts = df.groupby([group_column, bin_column]).size()\n",
198
+ " group_totals = group_counts.groupby(level=0).sum()\n",
199
+ " proportions = group_counts / group_totals\n",
200
+ " proportion_df = proportions.unstack(fill_value=0)\n",
201
+ "\n",
202
+ " ax = proportion_df.plot(kind='bar', stacked=True, colormap='viridis', figsize=(12, 8))\n",
203
+ " plt.title('Proportion of Volume Bins by Group')\n",
204
+ "\n",
205
+ " plt.xlabel('Group')\n",
206
+ " plt.ylabel('Proportion')\n",
207
+ "\n",
208
+ " # Update legend with formatted labels, maintaining correct order\n",
209
+ " plt.legend(title=f'Classes', bbox_to_anchor=(1.05, 1), loc='upper left')\n",
210
+ " plt.ylim(0, 1)\n",
211
+ " fig = plt.gcf() \n",
212
+ " return chi2, p, dof, expected, raw_counts, fig\n",
213
+ " \n",
214
+ " #settings = set_analyze_endodyogeny_defaults(settings)\n",
215
+ " #save_settings(settings, name='analyze_endodyogeny', show=True)\n",
216
+ " output = {}\n",
217
+ "\n",
218
+ " # Process data\n",
219
+ " if not isinstance(settings['src'], list):\n",
220
+ " settings['src'] = [settings['src']]\n",
221
+ " \n",
222
+ " locs = []\n",
223
+ " for s in settings['src']:\n",
224
+ " loc = os.path.join(s, 'measurements/measurements.db')\n",
225
+ " locs.append(loc)\n",
226
+ " \n",
227
+ " if 'png_list' not in settings['tables']:\n",
228
+ " settings['tables'] = settings['tables'] + ['png_list']\n",
229
+ " \n",
230
+ " df, _ = _read_and_merge_data(\n",
231
+ " locs, \n",
232
+ " tables=settings['tables'], \n",
233
+ " verbose=settings['verbose'], \n",
234
+ " nuclei_limit=settings['nuclei_limit'], \n",
235
+ " pathogen_limit=settings['pathogen_limit']\n",
236
+ " )\n",
237
+ " \n",
238
+ " df = annotate_conditions(\n",
239
+ " df=df, \n",
240
+ " cells=settings['cell_types'], \n",
241
+ " cell_loc=settings['cell_plate_metadata'], \n",
242
+ " pathogens=settings['pathogen_types'],\n",
243
+ " pathogen_loc=settings['pathogen_plate_metadata'],\n",
244
+ " treatments=settings['treatments'], \n",
245
+ " treatment_loc=settings['treatment_plate_metadata']\n",
246
+ " )\n",
247
+ " \n",
248
+ " if settings['group_column'] not in df.columns:\n",
249
+ " print(f\"{settings['group_column']} not found in DataFrame, please choose from:\")\n",
250
+ " for col in df.columns:\n",
251
+ " print(col)\n",
252
+ " \n",
253
+ " df[settings['class_column']] = df[settings['class_column']].fillna(0)\n",
254
+ " output['data'] = df\n",
255
+ " \n",
256
+ " # Perform chi-squared test and plot\n",
257
+ " chi2, p, dof, expected, raw_counts, fig = _plot_proportion_stacked_bars(settings, df, settings['group_column'], bin_column=settings['class_column'], level=settings['level'])\n",
258
+ "\n",
259
+ " # Create a DataFrame with chi-squared test results and raw counts\n",
260
+ " results_df = pd.DataFrame({\n",
261
+ " 'chi_squared_stat': [chi2],\n",
262
+ " 'p_value': [p],\n",
263
+ " 'degrees_of_freedom': [dof]\n",
264
+ " })\n",
265
+ " \n",
266
+ " output['chi_squared'] = results_df\n",
267
+ " \n",
268
+ " if settings['save']:\n",
269
+ " output_dir = os.path.join(settings['src'][0], 'results')\n",
270
+ " os.makedirs(output_dir, exist_ok=True)\n",
271
+ " output_path_chi = os.path.join(output_dir, 'class_chi_squared_results.csv')\n",
272
+ " output_path_data = os.path.join(output_dir, 'class_chi_squared_data.csv')\n",
273
+ " output_path_fig = os.path.join(output_dir, 'class_chi_squared.pdf')\n",
274
+ " fig.savefig(output_path_fig, dpi=300, bbox_inches='tight')\n",
275
+ " results_df.to_csv(output_path_chi, index=False)\n",
276
+ " df.to_csv(output_path_data, index=False)\n",
277
+ " print(f\"Chi-squared results saved to {output_path_chi}\")\n",
278
+ " print(f\"Annotated data saved to {output_path_data}\")\n",
279
+ "\n",
280
+ " plt.show() \n",
281
+ "\n",
282
+ " return output\n",
283
+ "\n",
284
+ "%matplotlib inline\n",
285
+ "\n",
286
+ "settings = {\n",
287
+ " 'src': '/nas_mnt/carruthers/Einar/tsg101_screen/TSG101SCREEN_20240810_132824/plate1/',\n",
288
+ " 'tables': ['cell', 'nucleus', 'pathogen', 'cytoplasm'],\n",
289
+ " 'cell_types': ['Hela'],\n",
290
+ " 'cell_plate_metadata': None,\n",
291
+ " 'pathogen_types': ['nc', 'pc'],\n",
292
+ " 'pathogen_plate_metadata': [['c1'], ['c2']],\n",
293
+ " 'treatments': None,\n",
294
+ " 'treatment_plate_metadata': None,\n",
295
+ " 'group_column': 'pathogen',\n",
296
+ " 'class_column':'test',\n",
297
+ " 'pathogen_limit': 1,\n",
298
+ " 'nuclei_limit': 1000,\n",
299
+ " 'level': 'well',\n",
300
+ " 'save':True,\n",
301
+ " 'verbose': True}\n",
302
+ "\n",
303
+ "# Run the analysis\n",
304
+ "output = analyze_class_proportion(settings)\n"
305
+ ]
306
+ },
307
+ {
308
+ "cell_type": "code",
309
+ "execution_count": null,
310
+ "id": "adc1df67",
311
+ "metadata": {},
312
+ "outputs": [],
313
+ "source": []
314
+ }
315
+ ],
316
+ "metadata": {
317
+ "kernelspec": {
318
+ "display_name": "spacr",
319
+ "language": "python",
320
+ "name": "spacr"
321
+ },
322
+ "language_info": {
323
+ "codemirror_mode": {
324
+ "name": "ipython",
325
+ "version": 3
326
+ },
327
+ "file_extension": ".py",
328
+ "mimetype": "text/x-python",
329
+ "name": "python",
330
+ "nbconvert_exporter": "python",
331
+ "pygments_lexer": "ipython3",
332
+ "version": "3.9.19"
333
+ }
334
+ },
335
+ "nbformat": 4,
336
+ "nbformat_minor": 5
337
+ }