spacr 0.0.20__py3-none-any.whl → 0.0.21__py3-none-any.whl

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.
@@ -0,0 +1,72 @@
1
+ import csv
2
+ import os
3
+ import requests
4
+
5
+ def download_alphafold_structures(tsv_location, dst, version="4"):
6
+ # Create the destination directory if it does not exist
7
+ dst_pdb = os.path.join(dst,'pdb')
8
+ dst_cif = os.path.join(dst,'cif')
9
+ dst_pae = os.path.join(dst,'pae')
10
+
11
+ if not os.path.exists(dst):
12
+ os.makedirs(dst)
13
+ if not os.path.exists(dst_pdb):
14
+ os.makedirs(dst_pdb)
15
+ if not os.path.exists(dst_cif):
16
+ os.makedirs(dst_cif)
17
+ if not os.path.exists(dst_pae):
18
+ os.makedirs(dst_pae)
19
+
20
+ failed_downloads = [] # List to keep track of failed downloads
21
+
22
+ # Open the TSV file and read entries
23
+ with open(tsv_location, 'r') as tsv_file:
24
+ reader = csv.DictReader(tsv_file, delimiter='\t')
25
+ for row in reader:
26
+ entry = row['Entry']
27
+ af_link = f"https://alphafold.ebi.ac.uk/files/AF-{entry}-F1-model_v{version}.pdb"
28
+ cif_link = f"https://alphafold.ebi.ac.uk/files/AF-{entry}-F1-model_v{version}.cif"
29
+ pae_link = f"https://alphafold.ebi.ac.uk/files/AF-{entry}-F1-predicted_aligned_error_v{version}.json"
30
+
31
+ try:
32
+ response_pdb = requests.get(af_link, stream=True)
33
+ response_cif = requests.get(cif_link, stream=True)
34
+ response_pae = requests.get(pae_link, stream=True)
35
+ if response_pdb.status_code == 200:
36
+
37
+ # Save the PDB file
38
+ with open(os.path.join(dst_pdb, f"AF-{entry}-F1-model_v{version}.pdb"), 'wb') as pdb_file:
39
+ pdb_file.write(response_pdb.content)
40
+ print(f"Downloaded: AF-{entry}-F1-model_v{version}.pdb")
41
+
42
+ # Save the CIF file
43
+ with open(os.path.join(dst_cif, f"AF-{entry}-F1-model_v{version}.cif"), 'wb') as cif_file:
44
+ cif_file.write(response_cif.content)
45
+ print(f"Downloaded: AF-{entry}-F1-model_v{version}.cif")
46
+
47
+ # Save the PAE file
48
+ with open(os.path.join(dst_pae, f"AF-{entry}-F1-predicted_aligned_error_v{version}.json"), 'wb') as pdb_file:
49
+ pdb_file.write(response_pae.content)
50
+ print(f"Downloaded: AF-{entry}-F1-predicted_aligned_error_v{version}.json")
51
+
52
+ else:
53
+ # If the file could not be downloaded, record the entry
54
+ failed_downloads.append(entry)
55
+ print(f"Failed to download structure for: {entry}")
56
+ except Exception as e:
57
+ print(f"Error downloading structure for {entry}: {e}")
58
+ failed_downloads.append(entry)
59
+
60
+ # Save the list of failed downloads to a CSV file in the destination folder
61
+ if failed_downloads:
62
+ with open(os.path.join(dst, 'failed_downloads.csv'), 'w', newline='') as failed_file:
63
+ writer = csv.writer(failed_file)
64
+ writer.writerow(['Entry'])
65
+ for entry in failed_downloads:
66
+ writer.writerow([entry])
67
+ print(f"Failed download entries saved to: {os.path.join(dst, 'failed_downloads.csv')}")
68
+
69
+ # Example usage:
70
+ tsv_location = '/home/carruthers/Downloads/GT1_proteome/GT1_proteins_uniprot.tsv' # Replace with the path to your TSV file containing a list of UniProt entries
71
+ dst_folder = '/home/carruthers/Downloads/GT1_proteome' # Replace with your destination folder
72
+ download_alphafold_structures(tsv_location, dst_folder)
spacr/gui_mask_app.py CHANGED
@@ -1,4 +1,4 @@
1
- import spacr, sys, ctypes, csv, matplotlib
1
+ import sys, ctypes, matplotlib
2
2
  import tkinter as tk
3
3
  from tkinter import ttk, scrolledtext
4
4
  from ttkthemes import ThemedTk
@@ -16,11 +16,19 @@ except AttributeError:
16
16
  pass
17
17
 
18
18
  from .logger import log_function_call
19
- from .gui_utils import ScrollableFrame, StdoutRedirector, safe_literal_eval, clear_canvas, main_thread_update_function, create_dark_mode, set_dark_style, set_default_font, generate_fields, process_stdout_stderr
20
- from .gui_utils import mask_variables, check_mask_gui_settings, preprocess_generate_masks_wrapper, read_settings_from_csv, update_settings_from_csv #, add_mask_gui_defaults
19
+ from .gui_utils import ScrollableFrame, StdoutRedirector, clear_canvas, main_thread_update_function, create_dark_mode, set_dark_style, generate_fields, process_stdout_stderr, set_default_font, style_text_boxes
20
+ from .gui_utils import mask_variables, check_mask_gui_settings, preprocess_generate_masks_wrapper, read_settings_from_csv, update_settings_from_csv#, toggle_advanced_settings
21
21
 
22
22
  thread_control = {"run_thread": None, "stop_requested": False}
23
23
 
24
+ def toggle_advanced_settings():
25
+ advanced = advanced_var.get()
26
+ for widget in advanced_widgets:
27
+ if advanced:
28
+ widget.grid()
29
+ else:
30
+ widget.grid_remove()
31
+
24
32
  @log_function_call
25
33
  def initiate_abort():
26
34
  global thread_control
@@ -73,7 +81,7 @@ def import_settings(scrollable_frame):
73
81
 
74
82
  @log_function_call
75
83
  def initiate_mask_root(width, height):
76
- global root, vars_dict, q, canvas, fig_queue, canvas_widget, thread_control
84
+ global root, vars_dict, q, canvas, fig_queue, canvas_widget, thread_control, advanced_widgets, advanced_var
77
85
 
78
86
  theme = 'breeze'
79
87
 
@@ -87,7 +95,8 @@ def initiate_mask_root(width, height):
87
95
  style = ttk.Style(root)
88
96
  set_dark_style(style)
89
97
 
90
- set_default_font(root, font_name="Arial", size=10)
98
+ style_text_boxes(style)
99
+ set_default_font(root, font_name="Arial", size=8)
91
100
  #root.state('zoomed') # For Windows to maximize the window
92
101
  root.attributes('-fullscreen', True)
93
102
  root.geometry(f"{width}x{height}")
@@ -139,6 +148,10 @@ def initiate_mask_root(width, height):
139
148
  # Setup for user input fields (variables)
140
149
  variables = mask_variables()
141
150
  vars_dict = generate_fields(variables, scrollable_frame)
151
+ #del vars_dict['fps']
152
+
153
+ # Debugging: print vars_dict to ensure it is populated correctly
154
+ #print("vars_dict:", vars_dict)
142
155
 
143
156
  # Horizontal container for Matplotlib figure and the vertical pane (for settings and console)
144
157
  horizontal_container = tk.PanedWindow(vertical_container, orient=tk.VERTICAL) #HORIZONTAL
@@ -167,21 +180,27 @@ def initiate_mask_root(width, height):
167
180
  q = Queue()
168
181
  sys.stdout = StdoutRedirector(console_output)
169
182
  sys.stderr = StdoutRedirector(console_output)
183
+
184
+ advanced_var = tk.BooleanVar()
185
+ advanced_checkbox = ttk.Checkbutton(scrollable_frame.scrollable_frame, text="Advanced Settings", variable=advanced_var, command=toggle_advanced_settings)
186
+ advanced_checkbox.grid(row=46, column=1, pady=10, padx=10)
170
187
 
171
188
  # This is your GUI setup where you create the Run button
172
189
  run_button = ttk.Button(scrollable_frame.scrollable_frame, text="Run",command=lambda: start_process(q, fig_queue))
173
- run_button.grid(row=45, column=0, pady=10)
190
+ run_button.grid(row=45, column=0, pady=10, padx=10)
174
191
 
175
192
  abort_button = ttk.Button(scrollable_frame.scrollable_frame, text="Abort", command=initiate_abort)
176
- abort_button.grid(row=45, column=1, pady=10)
193
+ abort_button.grid(row=45, column=1, pady=10, padx=10)
177
194
 
178
195
  progress_label = ttk.Label(scrollable_frame.scrollable_frame, text="Processing: 0%", background="#333333", foreground="white")
179
- progress_label.grid(row=41, column=0, columnspan=2, sticky="ew", pady=(5, 0))
180
-
196
+ progress_label.grid(row=41, column=0, columnspan=2, sticky="ew", pady=(5, 0), padx=10)
197
+
181
198
  # Create the Import Settings button
182
199
  import_btn = tk.Button(root, text="Import Settings", command=lambda: import_settings(scrollable_frame))
183
- import_btn.pack(pady=20)
200
+ import_btn.pack(pady=20, padx=10)
201
+
184
202
 
203
+
185
204
  _process_console_queue()
186
205
  _process_fig_queue()
187
206
  create_dark_mode(root, style, console_output)
@@ -193,6 +212,7 @@ def initiate_mask_root(width, height):
193
212
  def gui_mask():
194
213
  global vars_dict, root
195
214
  root, vars_dict = initiate_mask_root(1000, 1500)
215
+
196
216
  root.mainloop()
197
217
 
198
218
  if __name__ == "__main__":
spacr/gui_utils.py CHANGED
@@ -14,6 +14,21 @@ except AttributeError:
14
14
 
15
15
  from .logger import log_function_call
16
16
 
17
+ def set_default_font(root, font_name="Helvetica", size=12):
18
+ default_font = (font_name, size)
19
+ root.option_add("*Font", default_font)
20
+ root.option_add("*TButton.Font", default_font)
21
+ root.option_add("*TLabel.Font", default_font)
22
+ root.option_add("*TEntry.Font", default_font)
23
+
24
+ def style_text_boxes(style):
25
+ style.configure('TEntry', padding='5 5 5 5', borderwidth=1, relief='solid', background='#333333', foreground='#ffffff')
26
+ style.configure('TButton', padding='10 10 10 10', borderwidth=1, relief='solid', background='#444444', foreground='#ffffff', font=('Helvetica', 12, 'bold'))
27
+ style.map('TButton',
28
+ background=[('active', '#555555'), ('disabled', '#222222')],
29
+ foreground=[('active', '#ffffff'), ('disabled', '#888888')])
30
+ style.configure('TLabel', padding='5 5 5 5', borderwidth=1, relief='flat', background='#2e2e2e', foreground='#ffffff')
31
+
17
32
  def read_settings_from_csv(csv_file_path):
18
33
  settings = {}
19
34
  with open(csv_file_path, newline='') as csvfile:
@@ -51,7 +66,7 @@ def disable_interactivity(fig):
51
66
  for handler_id in list(handlers.keys()):
52
67
  fig.canvas.mpl_disconnect(handler_id)
53
68
 
54
- def set_default_font(app, font_name="Arial Bold", size=10):
69
+ def set_default_font_v1(app, font_name="Arial Bold", size=10):
55
70
  default_font = nametofont("TkDefaultFont")
56
71
  text_font = nametofont("TkTextFont")
57
72
  fixed_font = nametofont("TkFixedFont")
@@ -580,7 +595,7 @@ def measure_crop_wrapper(settings, q, fig_queue):
580
595
 
581
596
  try:
582
597
  print('start')
583
- spacr.measure.measure_crop(settings=settings, annotation_settings={}, advanced_settings={})
598
+ spacr.measure.measure_crop(settings=settings)
584
599
  except Exception as e:
585
600
  errorMessage = f"Error during processing: {e}"
586
601
  q.put(errorMessage) # Send the error message to the GUI via the queue