spacr 0.1.16__tar.gz → 0.1.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 (64) hide show
  1. {spacr-0.1.16/spacr.egg-info → spacr-0.1.55}/PKG-INFO +2 -1
  2. {spacr-0.1.16 → spacr-0.1.55}/setup.py +7 -6
  3. {spacr-0.1.16 → spacr-0.1.55}/spacr/__init__.py +4 -1
  4. {spacr-0.1.16 → spacr-0.1.55}/spacr/app_annotate.py +3 -3
  5. spacr-0.1.55/spacr/app_classify.py +8 -0
  6. {spacr-0.1.16 → spacr-0.1.55}/spacr/app_make_masks.py +3 -3
  7. spacr-0.1.55/spacr/app_mask.py +8 -0
  8. spacr-0.1.55/spacr/app_measure.py +8 -0
  9. spacr-0.1.55/spacr/app_sequencing.py +8 -0
  10. spacr-0.1.55/spacr/app_umap.py +8 -0
  11. {spacr-0.1.16 → spacr-0.1.55}/spacr/core.py +8 -6
  12. {spacr-0.1.16 → spacr-0.1.55}/spacr/deep_spacr.py +3 -1
  13. {spacr-0.1.16 → spacr-0.1.55}/spacr/gui.py +28 -13
  14. spacr-0.1.55/spacr/gui_utils.py +1212 -0
  15. {spacr-0.1.16 → spacr-0.1.55}/spacr/measure.py +24 -3
  16. {spacr-0.1.16 → spacr-0.1.55}/spacr/sequencing.py +1 -17
  17. spacr-0.1.55/spacr/settings.py +911 -0
  18. {spacr-0.1.16 → spacr-0.1.55}/spacr/utils.py +59 -5
  19. {spacr-0.1.16 → spacr-0.1.55/spacr.egg-info}/PKG-INFO +2 -1
  20. {spacr-0.1.16 → spacr-0.1.55}/spacr.egg-info/SOURCES.txt +2 -1
  21. spacr-0.1.55/spacr.egg-info/entry_points.txt +8 -0
  22. {spacr-0.1.16 → spacr-0.1.55}/spacr.egg-info/requires.txt +1 -0
  23. spacr-0.1.16/spacr/app_classify.py +0 -206
  24. spacr-0.1.16/spacr/app_make_masks_v2.py +0 -686
  25. spacr-0.1.16/spacr/app_mask.py +0 -253
  26. spacr-0.1.16/spacr/app_measure.py +0 -253
  27. spacr-0.1.16/spacr/gui_utils.py +0 -1205
  28. spacr-0.1.16/spacr/settings.py +0 -477
  29. spacr-0.1.16/spacr.egg-info/entry_points.txt +0 -8
  30. {spacr-0.1.16 → spacr-0.1.55}/LICENSE +0 -0
  31. {spacr-0.1.16 → spacr-0.1.55}/MANIFEST.in +0 -0
  32. {spacr-0.1.16 → spacr-0.1.55}/README.rst +0 -0
  33. {spacr-0.1.16 → spacr-0.1.55}/setup.cfg +0 -0
  34. {spacr-0.1.16 → spacr-0.1.55}/spacr/__main__.py +0 -0
  35. {spacr-0.1.16 → spacr-0.1.55}/spacr/chris.py +0 -0
  36. {spacr-0.1.16 → spacr-0.1.55}/spacr/graph_learning.py +0 -0
  37. {spacr-0.1.16 → spacr-0.1.55}/spacr/io.py +0 -0
  38. {spacr-0.1.16 → spacr-0.1.55}/spacr/logger.py +0 -0
  39. {spacr-0.1.16 → spacr-0.1.55}/spacr/models/cp/toxo_plaque_cyto_e25000_X1120_Y1120.CP_model +0 -0
  40. {spacr-0.1.16 → spacr-0.1.55}/spacr/models/cp/toxo_plaque_cyto_e25000_X1120_Y1120.CP_model_settings.csv +0 -0
  41. {spacr-0.1.16 → spacr-0.1.55}/spacr/models/cp/toxo_pv_lumen.CP_model +0 -0
  42. {spacr-0.1.16 → spacr-0.1.55}/spacr/plot.py +0 -0
  43. {spacr-0.1.16 → spacr-0.1.55}/spacr/sim.py +0 -0
  44. {spacr-0.1.16 → spacr-0.1.55}/spacr/sim_app.py +0 -0
  45. {spacr-0.1.16 → spacr-0.1.55}/spacr/timelapse.py +0 -0
  46. {spacr-0.1.16 → spacr-0.1.55}/spacr/version.py +0 -0
  47. {spacr-0.1.16 → spacr-0.1.55}/spacr.egg-info/dependency_links.txt +0 -0
  48. {spacr-0.1.16 → spacr-0.1.55}/spacr.egg-info/top_level.txt +0 -0
  49. {spacr-0.1.16 → spacr-0.1.55}/tests/test_annotate_app.py +0 -0
  50. {spacr-0.1.16 → spacr-0.1.55}/tests/test_core.py +0 -0
  51. {spacr-0.1.16 → spacr-0.1.55}/tests/test_gui_classify_app.py +0 -0
  52. {spacr-0.1.16 → spacr-0.1.55}/tests/test_gui_mask_app.py +0 -0
  53. {spacr-0.1.16 → spacr-0.1.55}/tests/test_gui_measure_app.py +0 -0
  54. {spacr-0.1.16 → spacr-0.1.55}/tests/test_gui_sim_app.py +0 -0
  55. {spacr-0.1.16 → spacr-0.1.55}/tests/test_gui_utils.py +0 -0
  56. {spacr-0.1.16 → spacr-0.1.55}/tests/test_io.py +0 -0
  57. {spacr-0.1.16 → spacr-0.1.55}/tests/test_mask_app.py +0 -0
  58. {spacr-0.1.16 → spacr-0.1.55}/tests/test_measure.py +0 -0
  59. {spacr-0.1.16 → spacr-0.1.55}/tests/test_plot.py +0 -0
  60. {spacr-0.1.16 → spacr-0.1.55}/tests/test_sim.py +0 -0
  61. {spacr-0.1.16 → spacr-0.1.55}/tests/test_timelapse.py +0 -0
  62. {spacr-0.1.16 → spacr-0.1.55}/tests/test_train.py +0 -0
  63. {spacr-0.1.16 → spacr-0.1.55}/tests/test_umap.py +0 -0
  64. {spacr-0.1.16 → spacr-0.1.55}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: spacr
3
- Version: 0.1.16
3
+ Version: 0.1.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
@@ -39,6 +39,7 @@ Requires-Dist: ttf_opensans>=2020.10.30
39
39
  Requires-Dist: customtkinter<6.0,>=5.2.2
40
40
  Requires-Dist: biopython<2.0,>=1.80
41
41
  Requires-Dist: lxml<6.0,>=5.1.0
42
+ Requires-Dist: huggingface-hub<0.25,>=0.24.0
42
43
  Provides-Extra: dev
43
44
  Requires-Dist: pytest<3.11,>=3.9; extra == "dev"
44
45
  Provides-Extra: headless
@@ -44,12 +44,13 @@ dependencies = [
44
44
  'ttf_opensans>=2020.10.30',
45
45
  'customtkinter>=5.2.2,<6.0',
46
46
  'biopython>=1.80,<2.0',
47
- 'lxml>=5.1.0,<6.0'
47
+ 'lxml>=5.1.0,<6.0',
48
+ 'huggingface-hub>=0.24.0,<0.25'
48
49
  ]
49
50
 
50
51
  setup(
51
52
  name="spacr",
52
- version="0.1.16",
53
+ version="0.1.55",
53
54
  author="Einar Birnir Olafsson",
54
55
  author_email="olafsson@med.umich.com",
55
56
  description="Spatial phenotype analysis of crisp screens (SpaCr)",
@@ -61,11 +62,11 @@ setup(
61
62
  install_requires=dependencies,
62
63
  entry_points={
63
64
  'console_scripts': [
64
- 'mask=spacr.app_mask:gui_mask',
65
- 'measure=spacr.app_measure:gui_measure',
66
- 'make_masks=spacr.app_make_mask:gui_make_masks',
65
+ 'mask=spacr.app_mask:start_mask_app',
66
+ 'measure=spacr.app_measure:start_measure_app',
67
+ 'make_masks=spacr.app_make_masks:gui_make_masks',
67
68
  'annotate=spacr.app_annotate:gui_annotate',
68
- 'classify=spacr.app_classify:gui_classify',
69
+ 'classify=spacr.app_classify:start_classify_app',
69
70
  'sim=spacr.app_sim:gui_sim',
70
71
  'spacr=spacr.gui:gui_app',
71
72
  ],
@@ -15,10 +15,11 @@ from . import deep_spacr
15
15
  from . import app_annotate
16
16
  from . import gui_utils
17
17
  from . import app_make_masks
18
- from . import app_make_masks_v2
19
18
  from . import app_mask
20
19
  from . import app_measure
21
20
  from . import app_classify
21
+ from . import app_sequencing
22
+ from . import app_umap
22
23
  from . import logger
23
24
 
24
25
 
@@ -40,6 +41,8 @@ __all__ = [
40
41
  "app_mask",
41
42
  "app_measure",
42
43
  "app_classify",
44
+ "app_sequencing",
45
+ "app_umap",
43
46
  "logger"
44
47
  ]
45
48
 
@@ -13,7 +13,7 @@ from IPython.display import display, HTML
13
13
  from tkinter import font as tkFont
14
14
  from tkinter import TclError
15
15
 
16
- from .gui_utils import ScrollableFrame, CustomButton, set_dark_style, set_default_font, set_dark_style, create_menu_bar
16
+ from .gui_utils import spacrFrame, spacrButton, set_dark_style, create_menu_bar, set_default_font
17
17
 
18
18
  class ImageApp:
19
19
  def __init__(self, root, db_path, src, image_type=None, channels=None, grid_rows=None, grid_cols=None, image_size=(200, 200), annotation_column='annotate', normalize=False, percentiles=(1,99), measurement=None, threshold=None):
@@ -379,7 +379,7 @@ def initiate_annotation_app_root(parent_frame):
379
379
  container = tk.PanedWindow(parent_frame, orient=tk.HORIZONTAL, bg='black')
380
380
  container.pack(fill=tk.BOTH, expand=True)
381
381
 
382
- scrollable_frame = ScrollableFrame(container, bg='black')
382
+ scrollable_frame = spacrFrame(container, bg='black')
383
383
  container.add(scrollable_frame, stretch="always")
384
384
 
385
385
  # Setup input fields
@@ -444,7 +444,7 @@ def initiate_annotation_app_root(parent_frame):
444
444
  # Start the annotate application in the same root window
445
445
  annotate_app(parent_frame, settings)
446
446
 
447
- run_button = CustomButton(scrollable_frame.scrollable_frame, text="Run", command=run_app,
447
+ run_button = spacrButton(scrollable_frame.scrollable_frame, text="Run", command=run_app,
448
448
  font=tkFont.Font(family="Arial", size=12, weight=tkFont.NORMAL))
449
449
  run_button.grid(row=row, column=0, columnspan=2, pady=10, padx=10)
450
450
 
@@ -0,0 +1,8 @@
1
+ from .gui import MainApp
2
+
3
+ def start_classify_app():
4
+ app = MainApp(default_app="Classify")
5
+ app.mainloop()
6
+
7
+ if __name__ == "__main__":
8
+ start_classify_app()
@@ -13,7 +13,7 @@ from ttkthemes import ThemedTk
13
13
 
14
14
  from .logger import log_function_call
15
15
 
16
- from .gui_utils import ScrollableFrame, CustomButton, set_dark_style, set_default_font, set_dark_style, create_menu_bar
16
+ from .gui_utils import spacrFrame, spacrButton, set_dark_style, create_menu_bar, set_default_font
17
17
 
18
18
  class modify_masks:
19
19
 
@@ -869,7 +869,7 @@ def initiate_mask_app_root(parent_frame):
869
869
  container = tk.PanedWindow(parent_frame, orient=tk.HORIZONTAL)
870
870
  container.pack(fill=tk.BOTH, expand=True)
871
871
 
872
- scrollable_frame = ScrollableFrame(container, bg='black')
872
+ scrollable_frame = spacrFrame(container, bg='black')
873
873
  container.add(scrollable_frame, stretch="always")
874
874
 
875
875
  # Setup input fields
@@ -897,7 +897,7 @@ def initiate_mask_app_root(parent_frame):
897
897
  # Start the modify_masks application in the same root window
898
898
  app_instance = modify_masks(parent_frame, folder_path, scale_factor)
899
899
 
900
- run_button = CustomButton(scrollable_frame.scrollable_frame, text="Run", command=run_app)
900
+ run_button = spacrButton(scrollable_frame.scrollable_frame, text="Run", command=run_app)
901
901
  run_button.grid(row=row, column=0, columnspan=2, pady=10, padx=10)
902
902
 
903
903
  return parent_frame
@@ -0,0 +1,8 @@
1
+ from .gui import MainApp
2
+
3
+ def start_mask_app():
4
+ app = MainApp(default_app="Mask")
5
+ app.mainloop()
6
+
7
+ if __name__ == "__main__":
8
+ start_mask_app()
@@ -0,0 +1,8 @@
1
+ from .gui import MainApp
2
+
3
+ def start_measure_app():
4
+ app = MainApp(default_app="Measure")
5
+ app.mainloop()
6
+
7
+ if __name__ == "__main__":
8
+ start_measure_app()
@@ -0,0 +1,8 @@
1
+ from .gui import MainApp
2
+
3
+ def start_seq_app():
4
+ app = MainApp(default_app="Sequencing")
5
+ app.mainloop()
6
+
7
+ if __name__ == "__main__":
8
+ start_seq_app()
@@ -0,0 +1,8 @@
1
+ from .gui import MainApp
2
+
3
+ def start_umap_app():
4
+ app = MainApp(default_app="Umap")
5
+ app.mainloop()
6
+
7
+ if __name__ == "__main__":
8
+ start_umap_app()
@@ -3021,9 +3021,9 @@ def generate_image_umap(settings={}):
3021
3021
  """
3022
3022
 
3023
3023
  from .io import _read_and_join_tables
3024
- from .utils import get_db_paths, preprocess_data, reduction_and_clustering, remove_noise, generate_colors, correct_paths, plot_embedding, plot_clusters_grid, cluster_feature_analysis, generate_umap_from_images
3025
- from .settings import get_umap_image_settings
3026
- settings = get_umap_image_settings(settings)
3024
+ from .utils import get_db_paths, preprocess_data, reduction_and_clustering, remove_noise, generate_colors, correct_paths, plot_embedding, plot_clusters_grid, cluster_feature_analysis #, generate_umap_from_images
3025
+ from .settings import set_default_umap_image_settings
3026
+ settings = set_default_umap_image_settings(settings)
3027
3027
 
3028
3028
  if isinstance(settings['src'], str):
3029
3029
  settings['src'] = [settings['src']]
@@ -3109,7 +3109,9 @@ def generate_image_umap(settings={}):
3109
3109
 
3110
3110
  else:
3111
3111
  if settings['resnet_features']:
3112
- numeric_data, embedding, labels = generate_umap_from_images(image_paths, settings['n_neighbors'], settings['min_dist'], settings['metric'], settings['clustering'], settings['eps'], settings['min_samples'], settings['n_jobs'], settings['verbose'])
3112
+ # placeholder for resnet features, not implemented yet
3113
+ pass
3114
+ #numeric_data, embedding, labels = generate_umap_from_images(image_paths, settings['n_neighbors'], settings['min_dist'], settings['metric'], settings['clustering'], settings['eps'], settings['min_samples'], settings['n_jobs'], settings['verbose'])
3113
3115
  else:
3114
3116
  # Apply the trained reducer to the entire dataset
3115
3117
  numeric_data = preprocess_data(all_df, settings['filter_by'], settings['remove_highly_correlated'], settings['log_data'], settings['exclude'])
@@ -3205,9 +3207,9 @@ def reducer_hyperparameter_search(settings={}, reduction_params=None, dbscan_par
3205
3207
 
3206
3208
  from .io import _read_and_join_tables
3207
3209
  from .utils import get_db_paths, preprocess_data, search_reduction_and_clustering, generate_colors
3208
- from .settings import get_umap_image_settings
3210
+ from .settings import set_default_umap_image_settings
3209
3211
 
3210
- settings = get_umap_image_settings(settings)
3212
+ settings = set_default_umap_image_settings(settings)
3211
3213
  pointsize = settings['dot_size']
3212
3214
  if isinstance(dbscan_params, dict):
3213
3215
  dbscan_params = [dbscan_params]
@@ -10,6 +10,9 @@ import matplotlib.pyplot as plt
10
10
  from PIL import Image
11
11
 
12
12
  from .logger import log_function_call
13
+ from .utils import close_multiprocessing_processes, reset_mp
14
+ #reset_mp()
15
+ #close_multiprocessing_processes()
13
16
 
14
17
  def evaluate_model_core(model, loader, loader_name, epoch, loss_type):
15
18
  """
@@ -42,7 +45,6 @@ def evaluate_model_core(model, loader, loader_name, epoch, loss_type):
42
45
  for batch_idx, (data, target, _) in enumerate(loader, start=1):
43
46
  start_time = time.time()
44
47
  data, target = data.to(device), target.to(device).float()
45
- #data, target = data.to(torch.float).to(device), target.to(device).float()
46
48
  output = model(data)
47
49
  loss += F.binary_cross_entropy_with_logits(output, target, reduction='sum').item()
48
50
  loss = calculate_loss(output, target, loss_type=loss_type)
@@ -1,20 +1,15 @@
1
1
  import tkinter as tk
2
2
  from tkinter import ttk
3
- from tkinter import font as tkFont
4
3
  from PIL import Image, ImageTk
5
4
  import os
6
5
  import requests
7
-
8
- # Import your GUI apps
9
- from .app_mask import initiate_mask_root
10
- from .app_measure import initiate_measure_root
6
+ from multiprocessing import set_start_method
7
+ from .gui_utils import set_dark_style, create_menu_bar, initiate_root, spacrButton
11
8
  from .app_annotate import initiate_annotation_app_root
12
9
  from .app_make_masks import initiate_mask_app_root
13
- from .app_classify import initiate_classify_root
14
- from .gui_utils import CustomButton, set_dark_style, create_menu_bar
15
10
 
16
11
  class MainApp(tk.Tk):
17
- def __init__(self):
12
+ def __init__(self, default_app=None):
18
13
  super().__init__()
19
14
  width = self.winfo_screenwidth()
20
15
  height = self.winfo_screenheight()
@@ -25,16 +20,34 @@ class MainApp(tk.Tk):
25
20
  set_dark_style(style)
26
21
 
27
22
  self.gui_apps = {
28
- "Mask": (initiate_mask_root, "Generate cellpose masks for cells, nuclei and pathogen images."),
29
- "Measure": (initiate_measure_root, "Measure single object intensity and morphological feature. Crop and save single object image"),
23
+ "Mask": (lambda frame: initiate_root(frame, 'mask'), "Generate cellpose masks for cells, nuclei and pathogen images."),
24
+ "Measure": (lambda frame: initiate_root(frame, 'measure'), "Measure single object intensity and morphological feature. Crop and save single object image"),
30
25
  "Annotate": (initiate_annotation_app_root, "Annotation single object images on a grid. Annotations are saved to database."),
31
26
  "Make Masks": (initiate_mask_app_root, "Adjust pre-existing Cellpose models to your specific dataset for improved performance"),
32
- "Classify": (initiate_classify_root, "Train Torch Convolutional Neural Networks (CNNs) or Transformers to classify single object images.")
27
+ "Classify": (lambda frame: initiate_root(frame, 'classify'), "Train Torch Convolutional Neural Networks (CNNs) or Transformers to classify single object images."),
28
+ "Sequencing": (lambda frame: initiate_root(frame, 'sequencing'), "Analyze sequensing data."),
29
+ "Umap": (lambda frame: initiate_root(frame, 'umap'), "Generate UMAP embedings with datapoints represented as images.")
33
30
  }
34
31
 
35
32
  self.selected_app = tk.StringVar()
36
33
  self.create_widgets()
37
34
 
35
+
36
+ if default_app == "Mask":
37
+ self.load_app(default_app, self.gui_apps[default_app][0])
38
+ elif default_app == "Measure":
39
+ self.load_app(default_app, self.gui_apps[default_app][1])
40
+ elif default_app == "Annotate":
41
+ self.load_app(default_app, self.gui_apps[default_app][2])
42
+ elif default_app == "Make Masks":
43
+ self.load_app(default_app, self.gui_apps[default_app][3])
44
+ elif default_app == "Classify":
45
+ self.load_app(default_app, self.gui_apps[default_app][4])
46
+ elif default_app == "Sequencing":
47
+ self.load_app(default_app, self.gui_apps[default_app][5])
48
+ elif default_app == "Umap":
49
+ self.load_app(default_app, self.gui_apps[default_app][6])
50
+
38
51
  def create_widgets(self):
39
52
  # Create the menu bar
40
53
  create_menu_bar(self)
@@ -74,7 +87,8 @@ class MainApp(tk.Tk):
74
87
  app_func, app_desc = app_data
75
88
 
76
89
  # Create custom button with text
77
- button = CustomButton(buttons_frame, text=app_name, command=lambda app_name=app_name, app_func=app_func: self.load_app(app_name, app_func), font=('Helvetica', 12))
90
+ button = spacrButton(buttons_frame, text=app_name, command=lambda app_name=app_name, app_func=app_func: self.load_app(app_name, app_func), font=('Helvetica', 12))
91
+ #button = ttk.Button(buttons_frame, text=app_name, command=lambda app_name=app_name, app_func=app_func: self.load_app(app_name, app_func), style='Custom.TButton')
78
92
  button.grid(row=i, column=0, pady=10, padx=10, sticky="w")
79
93
 
80
94
  description_label = tk.Label(buttons_frame, text=app_desc, bg="black", fg="white", wraplength=800, justify="left", font=('Helvetica', 12))
@@ -146,4 +160,5 @@ def gui_app():
146
160
  app.mainloop()
147
161
 
148
162
  if __name__ == "__main__":
149
- gui_app()
163
+ set_start_method('spawn', force=True)
164
+ gui_app()