spacr 0.1.1__py3-none-any.whl → 0.1.7__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.
- spacr/__init__.py +18 -12
- spacr/annotate_app.py +258 -99
- spacr/annotate_app_v2.py +163 -4
- spacr/app_annotate.py +541 -0
- spacr/app_classify.py +8 -0
- spacr/app_make_masks.py +925 -0
- spacr/app_make_masks_v2.py +686 -0
- spacr/app_mask.py +8 -0
- spacr/app_measure.py +8 -0
- spacr/app_sequencing.py +8 -0
- spacr/app_umap.py +8 -0
- spacr/classify_app.py +201 -0
- spacr/core.py +30 -28
- spacr/deep_spacr.py +9 -7
- spacr/gui.py +50 -31
- spacr/gui_annotate.py +145 -0
- spacr/gui_classify_app.py +20 -6
- spacr/gui_core.py +608 -0
- spacr/gui_elements.py +324 -0
- spacr/gui_make_masks_app.py +927 -0
- spacr/gui_make_masks_app_v2.py +688 -0
- spacr/gui_mask_app.py +8 -4
- spacr/gui_measure_app.py +15 -5
- spacr/gui_run.py +58 -0
- spacr/gui_utils.py +80 -1026
- spacr/gui_wrappers.py +149 -0
- spacr/make_masks_app.py +929 -0
- spacr/make_masks_app_v2.py +688 -0
- spacr/mask_app.py +239 -915
- spacr/measure.py +35 -15
- spacr/measure_app.py +246 -0
- spacr/plot.py +53 -1
- spacr/sequencing.py +1 -17
- spacr/settings.py +502 -9
- spacr/sim_app.py +0 -0
- spacr/utils.py +73 -11
- {spacr-0.1.1.dist-info → spacr-0.1.7.dist-info}/METADATA +13 -22
- spacr-0.1.7.dist-info/RECORD +60 -0
- spacr-0.1.7.dist-info/entry_points.txt +8 -0
- spacr-0.1.1.dist-info/RECORD +0 -40
- spacr-0.1.1.dist-info/entry_points.txt +0 -9
- {spacr-0.1.1.dist-info → spacr-0.1.7.dist-info}/LICENSE +0 -0
- {spacr-0.1.1.dist-info → spacr-0.1.7.dist-info}/WHEEL +0 -0
- {spacr-0.1.1.dist-info → spacr-0.1.7.dist-info}/top_level.txt +0 -0
spacr/measure.py
CHANGED
@@ -16,12 +16,6 @@ from skimage.util import img_as_bool
|
|
16
16
|
|
17
17
|
from .logger import log_function_call
|
18
18
|
|
19
|
-
#from .io import create_database, _save_settings_to_db
|
20
|
-
#from .timelapse import _timelapse_masks_to_gif, _scmovie
|
21
|
-
#from .plot import _plot_cropped_arrays, _save_scimg_plot
|
22
|
-
#from .utils import _merge_overlapping_objects, _filter_object, _relabel_parent_with_child_labels, _exclude_objects
|
23
|
-
#from .utils import _merge_and_save_to_database, _crop_center, _find_bounding_box, _generate_names, _get_percentiles, normalize_to_dtype, _map_wells_png, _list_endpoint_subdirectories, _generate_representative_images
|
24
|
-
|
25
19
|
def get_components(cell_mask, nucleus_mask, pathogen_mask):
|
26
20
|
"""
|
27
21
|
Get the components (nucleus and pathogens) for each cell in the given masks.
|
@@ -617,10 +611,23 @@ def _measure_crop_core(index, time_ls, file, settings):
|
|
617
611
|
start = time.time()
|
618
612
|
try:
|
619
613
|
source_folder = os.path.dirname(settings['input_folder'])
|
614
|
+
#if not os.path.basename(source_folder).endswith('merged'):
|
615
|
+
# source_folder = os.path.join(source_folder, 'merged')
|
616
|
+
# print(f'changed source_folder to {source_folder}')
|
617
|
+
|
618
|
+
#if not os.path.exists(source_folder):
|
619
|
+
# return
|
620
|
+
|
620
621
|
file_name = os.path.splitext(file)[0]
|
621
622
|
data = np.load(os.path.join(settings['input_folder'], file))
|
622
|
-
|
623
623
|
data_type = data.dtype
|
624
|
+
if data_type not in ['uint8','uint16']:
|
625
|
+
data_type_before = data_type
|
626
|
+
data = data.astype(np.uint16)
|
627
|
+
data_type = data.dtype
|
628
|
+
if settings['verbose']:
|
629
|
+
print(f'Converted data from {data_type_before} to {data_type}')
|
630
|
+
|
624
631
|
if settings['save_measurements']:
|
625
632
|
os.makedirs(source_folder+'/measurements', exist_ok=True)
|
626
633
|
_create_database(source_folder+'/measurements/measurements.db')
|
@@ -750,6 +757,15 @@ def _measure_crop_core(index, time_ls, file, settings):
|
|
750
757
|
if isinstance(settings['crop_mode'], list):
|
751
758
|
crop_ls = settings['crop_mode']
|
752
759
|
size_ls = settings['png_size']
|
760
|
+
|
761
|
+
if isinstance(size_ls[0], int):
|
762
|
+
size_ls = [size_ls]
|
763
|
+
if len(crop_ls) > 1 and len(size_ls) == 1:
|
764
|
+
size_ls = size_ls * len(crop_ls)
|
765
|
+
|
766
|
+
if len(crop_ls) != len(size_ls):
|
767
|
+
print(f"Setting: size_ls: {settings['png_size']} should be a list of integers, or a list of lists of integers if crop_ls: {settings['crop_mode']} has multiple elements")
|
768
|
+
|
753
769
|
for crop_idx, crop_mode in enumerate(crop_ls):
|
754
770
|
width, height = size_ls[crop_idx]
|
755
771
|
if crop_mode == 'cell':
|
@@ -816,7 +832,6 @@ def _measure_crop_core(index, time_ls, file, settings):
|
|
816
832
|
png_channels = normalize_to_dtype(png_channels, settings['normalize'][0], settings['normalize'][1], percentile_list=percentile_list)
|
817
833
|
else:
|
818
834
|
png_channels = normalize_to_dtype(png_channels, 0, 100)
|
819
|
-
|
820
835
|
os.makedirs(png_folder, exist_ok=True)
|
821
836
|
|
822
837
|
if png_channels.shape[2] == 2:
|
@@ -926,9 +941,14 @@ def measure_crop(settings):
|
|
926
941
|
settings = get_measure_crop_settings(settings)
|
927
942
|
settings = measure_test_mode(settings)
|
928
943
|
|
929
|
-
|
930
|
-
|
931
|
-
|
944
|
+
#src_fldr = settings['input_folder']
|
945
|
+
#if not os.path.basename(src_fldr).endswith('merged'):
|
946
|
+
# settings['input_folder'] = os.path.join(src_fldr, 'merged')
|
947
|
+
# print(f"changed input_folder to {src_fldr}")
|
948
|
+
|
949
|
+
#if not os.path.exists(settings['input_folder']):
|
950
|
+
# print(f'input_folder: {settings["input_folder"]} does not exist')
|
951
|
+
# return
|
932
952
|
|
933
953
|
if settings['cell_mask_dim'] is None:
|
934
954
|
settings['include_uninfected'] = True
|
@@ -978,12 +998,12 @@ def measure_crop(settings):
|
|
978
998
|
_save_settings_to_db(settings)
|
979
999
|
|
980
1000
|
files = [f for f in os.listdir(settings['input_folder']) if f.endswith('.npy')]
|
981
|
-
|
982
|
-
print(f'using {
|
1001
|
+
n_job = settings['n_job'] or mp.cpu_count()-4
|
1002
|
+
print(f'using {n_job} cpu cores')
|
983
1003
|
|
984
1004
|
with mp.Manager() as manager:
|
985
1005
|
time_ls = manager.list()
|
986
|
-
with mp.Pool(
|
1006
|
+
with mp.Pool(n_job) as pool:
|
987
1007
|
result = pool.starmap_async(_measure_crop_core, [(index, time_ls, file, settings) for index, file in enumerate(files)])
|
988
1008
|
|
989
1009
|
# Track progress in the main process
|
@@ -992,7 +1012,7 @@ def measure_crop(settings):
|
|
992
1012
|
files_processed = len(time_ls)
|
993
1013
|
files_to_process = len(files)
|
994
1014
|
average_time = np.mean(time_ls) if len(time_ls) > 0 else 0
|
995
|
-
time_left = (((files_to_process-files_processed)*average_time)/
|
1015
|
+
time_left = (((files_to_process-files_processed)*average_time)/n_job)/60
|
996
1016
|
print(f'Progress: {files_processed}/{files_to_process} Time/img {average_time:.3f}sec, Time Remaining {time_left:.3f} min.', end='\r', flush=True)
|
997
1017
|
result.get()
|
998
1018
|
|
spacr/measure_app.py
ADDED
@@ -0,0 +1,246 @@
|
|
1
|
+
import sys, traceback, matplotlib, ctypes
|
2
|
+
import tkinter as tk
|
3
|
+
from tkinter import ttk, scrolledtext
|
4
|
+
from matplotlib.figure import Figure
|
5
|
+
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
|
6
|
+
matplotlib.use('Agg') # Use the non-GUI Agg backend
|
7
|
+
from multiprocessing import Process, Queue, Value
|
8
|
+
from tkinter import filedialog
|
9
|
+
|
10
|
+
try:
|
11
|
+
ctypes.windll.shcore.SetProcessDpiAwareness(True)
|
12
|
+
except AttributeError:
|
13
|
+
pass
|
14
|
+
|
15
|
+
from .logger import log_function_call
|
16
|
+
from .gui_utils import ScrollableFrame, StdoutRedirector, CustomButton, ToggleSwitch, ToolTip
|
17
|
+
from .gui_utils import process_stdout_stderr, set_dark_style, set_default_font, generate_fields, main_thread_update_function, create_menu_bar
|
18
|
+
from .gui_utils import measure_variables, measure_crop_wrapper, clear_canvas, check_measure_gui_settings, read_settings_from_csv, update_settings_from_csv, style_text_boxes
|
19
|
+
|
20
|
+
thread_control = {"run_thread": None, "stop_requested": False}
|
21
|
+
|
22
|
+
def import_settings(scrollable_frame):
|
23
|
+
global vars_dict
|
24
|
+
|
25
|
+
csv_file_path = filedialog.askopenfilename(filetypes=[("CSV files", "*.csv")])
|
26
|
+
csv_settings = read_settings_from_csv(csv_file_path)
|
27
|
+
variables = measure_variables()
|
28
|
+
new_settings = update_settings_from_csv(variables, csv_settings)
|
29
|
+
vars_dict = generate_fields(new_settings, scrollable_frame)
|
30
|
+
|
31
|
+
def toggle_test_mode():
|
32
|
+
global vars_dict
|
33
|
+
current_state = vars_dict['test_mode'][2].get()
|
34
|
+
new_state = not current_state
|
35
|
+
vars_dict['test_mode'][2].set(new_state)
|
36
|
+
if new_state:
|
37
|
+
test_mode_button.config(bg="blue")
|
38
|
+
else:
|
39
|
+
test_mode_button.config(bg="gray")
|
40
|
+
|
41
|
+
def toggle_advanced_settings():
|
42
|
+
global vars_dict
|
43
|
+
|
44
|
+
timelapse_settings = ['timelapse', 'timelapse_objects']
|
45
|
+
misc_settings = ['representative_images', 'plot', 'plot_filtration', 'include_uninfected', 'dialate_pngs', 'dialate_png_ratios']
|
46
|
+
opperational_settings = ['max_workers','experiment','cells','cell_loc','pathogens','pathogen_loc','treatments','treatment_loc','channel_of_interest','compartments','measurement','nr_imgs', 'um_per_pixel']
|
47
|
+
|
48
|
+
advanced_settings = timelapse_settings+misc_settings+opperational_settings
|
49
|
+
|
50
|
+
# Toggle visibility of advanced settings
|
51
|
+
for setting in advanced_settings:
|
52
|
+
label, widget, var = vars_dict[setting]
|
53
|
+
if advanced_var.get() is False:
|
54
|
+
label.grid_remove() # Hide the label
|
55
|
+
widget.grid_remove() # Hide the widget
|
56
|
+
else:
|
57
|
+
label.grid() # Show the label
|
58
|
+
widget.grid() # Show the widget
|
59
|
+
|
60
|
+
#@log_function_call
|
61
|
+
def run_measure_gui(q, fig_queue, stop_requested):
|
62
|
+
global vars_dict
|
63
|
+
process_stdout_stderr(q)
|
64
|
+
try:
|
65
|
+
print('hello')
|
66
|
+
settings = check_measure_gui_settings(vars_dict)
|
67
|
+
measure_crop_wrapper(settings=settings, q=q, fig_queue=fig_queue)
|
68
|
+
except Exception as e:
|
69
|
+
q.put(f"Error during processing: {e}")
|
70
|
+
traceback.print_exc()
|
71
|
+
finally:
|
72
|
+
stop_requested.value = 1
|
73
|
+
|
74
|
+
#@log_function_call
|
75
|
+
def start_process(q, fig_queue):
|
76
|
+
global thread_control
|
77
|
+
if thread_control.get("run_thread") is not None:
|
78
|
+
initiate_abort()
|
79
|
+
|
80
|
+
stop_requested = Value('i', 0) # multiprocessing shared value for inter-process communication
|
81
|
+
thread_control["stop_requested"] = stop_requested
|
82
|
+
thread_control["run_thread"] = Process(target=run_measure_gui, args=(q, fig_queue, stop_requested))
|
83
|
+
thread_control["run_thread"].start()
|
84
|
+
|
85
|
+
#@log_function_call
|
86
|
+
def initiate_abort():
|
87
|
+
global thread_control
|
88
|
+
if thread_control.get("stop_requested") is not None:
|
89
|
+
thread_control["stop_requested"].value = 1
|
90
|
+
|
91
|
+
if thread_control.get("run_thread") is not None:
|
92
|
+
thread_control["run_thread"].join(timeout=5)
|
93
|
+
if thread_control["run_thread"].is_alive():
|
94
|
+
thread_control["run_thread"].terminate()
|
95
|
+
thread_control["run_thread"] = None
|
96
|
+
|
97
|
+
#@log_function_call
|
98
|
+
def initiate_measure_root(parent_frame):
|
99
|
+
global vars_dict, q, canvas, fig_queue, canvas_widget, thread_control, variables, advanced_var, scrollable_frame
|
100
|
+
|
101
|
+
style = ttk.Style(parent_frame)
|
102
|
+
set_dark_style(style)
|
103
|
+
style_text_boxes(style)
|
104
|
+
set_default_font(parent_frame, font_name="Helvetica", size=8)
|
105
|
+
|
106
|
+
parent_frame.configure(bg='black')
|
107
|
+
parent_frame.grid_rowconfigure(0, weight=1)
|
108
|
+
parent_frame.grid_columnconfigure(0, weight=1)
|
109
|
+
|
110
|
+
fig_queue = Queue()
|
111
|
+
|
112
|
+
# Initialize after_tasks if not already done
|
113
|
+
if not hasattr(parent_frame, 'after_tasks'):
|
114
|
+
parent_frame.after_tasks = []
|
115
|
+
|
116
|
+
def _process_fig_queue():
|
117
|
+
global canvas
|
118
|
+
try:
|
119
|
+
while not fig_queue.empty():
|
120
|
+
clear_canvas(canvas)
|
121
|
+
fig = fig_queue.get_nowait()
|
122
|
+
for ax in fig.get_axes():
|
123
|
+
ax.set_xticks([]) # Remove x-axis ticks
|
124
|
+
ax.set_yticks([]) # Remove y-axis ticks
|
125
|
+
ax.xaxis.set_visible(False) # Hide the x-axis
|
126
|
+
ax.yaxis.set_visible(False) # Hide the y-axis
|
127
|
+
fig.tight_layout()
|
128
|
+
fig.set_facecolor('black')
|
129
|
+
canvas.figure = fig
|
130
|
+
fig_width, fig_height = canvas_widget.winfo_width(), canvas_widget.winfo_height()
|
131
|
+
fig.set_size_inches(fig_width / fig.dpi, fig_height / fig.dpi, forward=True)
|
132
|
+
canvas.draw_idle()
|
133
|
+
except Exception as e:
|
134
|
+
traceback.print_exc()
|
135
|
+
finally:
|
136
|
+
after_id = canvas_widget.after(100, _process_fig_queue)
|
137
|
+
parent_frame.after_tasks.append(after_id)
|
138
|
+
|
139
|
+
def _process_console_queue():
|
140
|
+
while not q.empty():
|
141
|
+
message = q.get_nowait()
|
142
|
+
console_output.insert(tk.END, message)
|
143
|
+
console_output.see(tk.END)
|
144
|
+
after_id = console_output.after(100, _process_console_queue)
|
145
|
+
parent_frame.after_tasks.append(after_id)
|
146
|
+
|
147
|
+
# Clear previous content if any
|
148
|
+
for widget in parent_frame.winfo_children():
|
149
|
+
widget.destroy()
|
150
|
+
|
151
|
+
vertical_container = tk.PanedWindow(parent_frame, orient=tk.HORIZONTAL)
|
152
|
+
vertical_container.grid(row=0, column=0, sticky=tk.NSEW)
|
153
|
+
parent_frame.grid_rowconfigure(0, weight=1)
|
154
|
+
parent_frame.grid_columnconfigure(0, weight=1)
|
155
|
+
|
156
|
+
# Settings Section
|
157
|
+
settings_frame = tk.Frame(vertical_container, bg='black')
|
158
|
+
vertical_container.add(settings_frame, stretch="always")
|
159
|
+
settings_label = ttk.Label(settings_frame, text="Settings", background="black", foreground="white")
|
160
|
+
settings_label.grid(row=0, column=0, pady=10, padx=10)
|
161
|
+
scrollable_frame = ScrollableFrame(settings_frame, width=500)
|
162
|
+
scrollable_frame.grid(row=1, column=0, sticky="nsew")
|
163
|
+
settings_frame.grid_rowconfigure(1, weight=1)
|
164
|
+
settings_frame.grid_columnconfigure(0, weight=1)
|
165
|
+
|
166
|
+
# Create advanced settings checkbox
|
167
|
+
advanced_var = tk.BooleanVar(value=False)
|
168
|
+
advanced_Toggle = ToggleSwitch(scrollable_frame.scrollable_frame, text="Advanced Settings", variable=advanced_var, command=toggle_advanced_settings)
|
169
|
+
advanced_Toggle.grid(row=48, column=0, pady=10, padx=10)
|
170
|
+
variables = measure_variables()
|
171
|
+
vars_dict = generate_fields(variables, scrollable_frame)
|
172
|
+
toggle_advanced_settings()
|
173
|
+
vars_dict['Test mode'] = (None, None, tk.BooleanVar(value=False))
|
174
|
+
|
175
|
+
# Button section
|
176
|
+
test_mode_button = CustomButton(scrollable_frame.scrollable_frame, text="Test Mode", command=toggle_test_mode)
|
177
|
+
test_mode_button.grid(row=47, column=1, pady=10, padx=10)
|
178
|
+
import_btn = CustomButton(scrollable_frame.scrollable_frame, text="Import", command=lambda: import_settings(scrollable_frame), font=('Helvetica', 10))
|
179
|
+
import_btn.grid(row=47, column=0, pady=20, padx=20)
|
180
|
+
run_button = CustomButton(scrollable_frame.scrollable_frame, text="Run", command=lambda: start_process(q, fig_queue), font=('Helvetica', 10))
|
181
|
+
run_button.grid(row=45, column=0, pady=20, padx=20)
|
182
|
+
abort_button = CustomButton(scrollable_frame.scrollable_frame, text="Abort", command=initiate_abort, font=('Helvetica', 10))
|
183
|
+
abort_button.grid(row=45, column=1, pady=20, padx=20)
|
184
|
+
progress_label = ttk.Label(scrollable_frame.scrollable_frame, text="Processing: 0%", background="black", foreground="white") # Create progress field
|
185
|
+
progress_label.grid(row=50, column=0, columnspan=2, sticky="ew", pady=(5, 0), padx=10)
|
186
|
+
|
187
|
+
# Plot Canvas Section
|
188
|
+
plot_frame = tk.PanedWindow(vertical_container, orient=tk.VERTICAL)
|
189
|
+
vertical_container.add(plot_frame, stretch="always")
|
190
|
+
figure = Figure(figsize=(30, 4), dpi=100, facecolor='black')
|
191
|
+
plot = figure.add_subplot(111)
|
192
|
+
plot.plot([], [])
|
193
|
+
plot.axis('off')
|
194
|
+
canvas = FigureCanvasTkAgg(figure, master=plot_frame)
|
195
|
+
canvas.get_tk_widget().configure(cursor='arrow', background='black', highlightthickness=0)
|
196
|
+
canvas_widget = canvas.get_tk_widget()
|
197
|
+
plot_frame.add(canvas_widget, stretch="always")
|
198
|
+
canvas.draw()
|
199
|
+
canvas.figure = figure
|
200
|
+
|
201
|
+
# Console Section
|
202
|
+
console_frame = tk.Frame(vertical_container, bg='black')
|
203
|
+
vertical_container.add(console_frame, stretch="always")
|
204
|
+
console_label = ttk.Label(console_frame, text="Console", background="black", foreground="white")
|
205
|
+
console_label.grid(row=0, column=0, pady=10, padx=10)
|
206
|
+
console_output = scrolledtext.ScrolledText(console_frame, height=10, bg='black', fg='white', insertbackground='white')
|
207
|
+
console_output.grid(row=1, column=0, sticky="nsew")
|
208
|
+
console_frame.grid_rowconfigure(1, weight=1)
|
209
|
+
console_frame.grid_columnconfigure(0, weight=1)
|
210
|
+
|
211
|
+
q = Queue()
|
212
|
+
sys.stdout = StdoutRedirector(console_output)
|
213
|
+
sys.stderr = StdoutRedirector(console_output)
|
214
|
+
|
215
|
+
_process_console_queue()
|
216
|
+
_process_fig_queue()
|
217
|
+
|
218
|
+
after_id = parent_frame.after(100, lambda: main_thread_update_function(parent_frame, q, fig_queue, canvas_widget, progress_label))
|
219
|
+
parent_frame.after_tasks.append(after_id)
|
220
|
+
|
221
|
+
return parent_frame, vars_dict
|
222
|
+
|
223
|
+
def gui_measure():
|
224
|
+
root = tk.Tk()
|
225
|
+
width = root.winfo_screenwidth()
|
226
|
+
height = root.winfo_screenheight()
|
227
|
+
root.geometry(f"{width}x{height}")
|
228
|
+
root.title("SpaCr: measure objects")
|
229
|
+
|
230
|
+
# Clear previous content if any
|
231
|
+
if hasattr(root, 'content_frame'):
|
232
|
+
for widget in root.content_frame.winfo_children():
|
233
|
+
widget.destroy()
|
234
|
+
root.content_frame.grid_forget()
|
235
|
+
else:
|
236
|
+
root.content_frame = tk.Frame(root)
|
237
|
+
root.content_frame.grid(row=1, column=0, sticky="nsew")
|
238
|
+
root.grid_rowconfigure(1, weight=1)
|
239
|
+
root.grid_columnconfigure(0, weight=1)
|
240
|
+
|
241
|
+
initiate_measure_root(root.content_frame)
|
242
|
+
create_menu_bar(root)
|
243
|
+
root.mainloop()
|
244
|
+
|
245
|
+
if __name__ == "__main__":
|
246
|
+
gui_measure()
|
spacr/plot.py
CHANGED
@@ -1565,4 +1565,56 @@ def plot_feature_importance(feature_importance_df):
|
|
1565
1565
|
ax.set_xlabel('Feature Importance', fontsize=font_size)
|
1566
1566
|
ax.tick_params(axis='both', which='major', labelsize=font_size)
|
1567
1567
|
plt.tight_layout()
|
1568
|
-
return fig
|
1568
|
+
return fig
|
1569
|
+
|
1570
|
+
def read_and_plot__vision_results(base_dir, y_axis='accuracy', name_split='_time', y_lim=[0.8, 0.9]):
|
1571
|
+
# List to store data from all CSV files
|
1572
|
+
data_frames = []
|
1573
|
+
|
1574
|
+
dst = os.path.join(base_dir, 'result')
|
1575
|
+
os.mkdir(dst,exists=True)
|
1576
|
+
|
1577
|
+
# Walk through the directory
|
1578
|
+
for root, dirs, files in os.walk(base_dir):
|
1579
|
+
for file in files:
|
1580
|
+
if file.endswith("_test_result.csv"):
|
1581
|
+
file_path = os.path.join(root, file)
|
1582
|
+
# Extract model information from the file name
|
1583
|
+
file_name = os.path.basename(file_path)
|
1584
|
+
model = file_name.split(f'{name_split}')[0]
|
1585
|
+
|
1586
|
+
# Extract epoch information from the file name
|
1587
|
+
epoch_info = file_name.split('_time')[1]
|
1588
|
+
base_folder = os.path.dirname(file_path)
|
1589
|
+
epoch = os.path.basename(base_folder)
|
1590
|
+
|
1591
|
+
# Read the CSV file
|
1592
|
+
df = pd.read_csv(file_path)
|
1593
|
+
df['model'] = model
|
1594
|
+
df['epoch'] = epoch
|
1595
|
+
|
1596
|
+
# Append the data frame to the list
|
1597
|
+
data_frames.append(df)
|
1598
|
+
|
1599
|
+
# Concatenate all data frames
|
1600
|
+
if data_frames:
|
1601
|
+
result_df = pd.concat(data_frames, ignore_index=True)
|
1602
|
+
|
1603
|
+
# Calculate average y_axis per model
|
1604
|
+
avg_metric = result_df.groupby('model')[y_axis].mean().reset_index()
|
1605
|
+
avg_metric = avg_metric.sort_values(by=y_axis)
|
1606
|
+
print(avg_metric)
|
1607
|
+
|
1608
|
+
# Plotting the results
|
1609
|
+
plt.figure(figsize=(10, 6))
|
1610
|
+
plt.bar(avg_metric['model'], avg_metric[y_axis])
|
1611
|
+
plt.xlabel('Model')
|
1612
|
+
plt.ylabel(f'{y_axis}')
|
1613
|
+
plt.title(f'Average {y_axis.capitalize()} per Model')
|
1614
|
+
plt.xticks(rotation=45)
|
1615
|
+
plt.tight_layout()
|
1616
|
+
if y_lim is not None:
|
1617
|
+
plt.ylim(y_lim)
|
1618
|
+
plt.show()
|
1619
|
+
else:
|
1620
|
+
print("No CSV files found in the specified directory.")
|
spacr/sequencing.py
CHANGED
@@ -37,22 +37,6 @@ def analyze_reads(settings):
|
|
37
37
|
None
|
38
38
|
"""
|
39
39
|
|
40
|
-
def save_chunk_to_hdf5_v1(output_file_path, data_chunk, chunk_counter):
|
41
|
-
"""
|
42
|
-
Save a data chunk to an HDF5 file.
|
43
|
-
|
44
|
-
Parameters:
|
45
|
-
- output_file_path (str): The path to the output HDF5 file.
|
46
|
-
- data_chunk (list): The data chunk to be saved.
|
47
|
-
- chunk_counter (int): The counter for the current chunk.
|
48
|
-
|
49
|
-
Returns:
|
50
|
-
None
|
51
|
-
"""
|
52
|
-
df = pd.DataFrame(data_chunk, columns=['combined_read', 'grna', 'plate_row', 'column', 'sample'])
|
53
|
-
with pd.HDFStore(output_file_path, mode='a', complevel=5, complib='blosc') as store:
|
54
|
-
store.put(f'reads/chunk_{chunk_counter}', df, format='table', append=True)
|
55
|
-
|
56
40
|
def save_chunk_to_hdf5(output_file_path, data_chunk, chunk_counter):
|
57
41
|
"""
|
58
42
|
Save a data chunk to an HDF5 file.
|
@@ -306,7 +290,7 @@ def analyze_reads(settings):
|
|
306
290
|
qc_df = pd.DataFrame([qc])
|
307
291
|
qc_df.to_csv(qc_file_path, index=False)
|
308
292
|
|
309
|
-
from .
|
293
|
+
from .settings import get_analyze_reads_default_settings
|
310
294
|
|
311
295
|
settings = get_analyze_reads_default_settings(settings)
|
312
296
|
|