Spaces:
Running
Running
Commit
·
88f2e9d
1
Parent(s):
c4683fa
uploaded other sizes to test and improved plot
Browse files- app.py +97 -51
- best_distances_0_5.pkl +3 -0
- best_distances_22_0.pkl +3 -0
- best_distances.pkl → best_distances_3_0.pkl +0 -0
app.py
CHANGED
@@ -16,12 +16,12 @@ def style_feasible_column(val):
|
|
16 |
return 'color:white;background-color: lightcoral'
|
17 |
return ''
|
18 |
|
19 |
-
def style_size_column(val):
|
20 |
"""Style for the Size column based on proximity to target"""
|
21 |
try:
|
22 |
val_float = float(val)
|
23 |
|
24 |
-
distance = val_float -
|
25 |
abs_distance = abs(distance)
|
26 |
|
27 |
# Calculate width percentage based on distance
|
@@ -86,18 +86,25 @@ exp_record_df['Size (um)'] = Y_init[:, 0]
|
|
86 |
exp_record_df['Solvent'] = ['DMAc' if x == 0 else 'CHCl3' for x in exp_record_df['Solvent']]
|
87 |
exp_record_df['Feasible?'] = ['Success' if x == 1 else 'Failed' for x in Y_init[:, 1]]
|
88 |
|
89 |
-
#
|
90 |
-
|
91 |
-
|
92 |
-
.
|
93 |
-
|
|
|
|
|
|
|
94 |
|
95 |
# Functions for data processing and visualization
|
96 |
-
def import_results():
|
97 |
strategies = ['qEI', 'qEI_vi_mixed_con', 'qEICF_vi_mixed_con', 'rnd']
|
98 |
-
|
99 |
-
|
100 |
-
|
|
|
|
|
|
|
|
|
101 |
best_distances = pickle.load(f)
|
102 |
|
103 |
# vstack all values in best_distances
|
@@ -110,14 +117,13 @@ def import_results():
|
|
110 |
best_distances_df_long = pd.melt(best_distances_all_trials_df, id_vars=['strategy', 'trial'], var_name='iteration', value_name='regret')
|
111 |
return best_distances_df_long
|
112 |
|
113 |
-
def calc_human_performance(df):
|
114 |
# Make a copy of the dataframe to avoid modifying the original
|
115 |
df_copy = df.copy()
|
116 |
|
117 |
# convert back solvent to 0 and 1
|
118 |
df_copy['Solvent'] = [0 if x == 'DMAc' else 1 for x in df_copy['Solvent']]
|
119 |
|
120 |
-
TARGET_SIZE = 3.0 # Example target size
|
121 |
ROUNDS = len(df_copy) // 2
|
122 |
|
123 |
# Ensure all values are numeric
|
@@ -133,7 +139,7 @@ def calc_human_performance(df):
|
|
133 |
best_human_distance = []
|
134 |
|
135 |
for iter in range(ROUNDS + 1):
|
136 |
-
Y_distance = -np.abs(Y_human_init[:, 0] -
|
137 |
best_human_distance.append(np.ma.masked_array(Y_distance, mask=~Y_human_init[:, 1].astype(bool)).max())
|
138 |
|
139 |
# Check if we have more data for this iteration
|
@@ -147,12 +153,12 @@ def calc_human_performance(df):
|
|
147 |
|
148 |
return -np.array(best_human_distance)
|
149 |
|
150 |
-
def plot_results(exp_data_df):
|
151 |
# Extract human performance
|
152 |
-
best_human_distance = calc_human_performance(exp_data_df)
|
153 |
|
154 |
# Import results
|
155 |
-
best_distances_df_long = import_results()
|
156 |
|
157 |
fig = go.Figure()
|
158 |
|
@@ -161,9 +167,12 @@ def plot_results(exp_data_df):
|
|
161 |
for strategy in strategies:
|
162 |
strategy_data = best_distances_df_long[best_distances_df_long['strategy'] == strategy]
|
163 |
|
164 |
-
# Calculate mean and standard
|
165 |
mean_regret = strategy_data.groupby('iteration')['regret'].mean()
|
166 |
std_regret = strategy_data.groupby('iteration')['regret'].std()
|
|
|
|
|
|
|
167 |
|
168 |
iterations = mean_regret.index
|
169 |
color = px.colors.qualitative.Set2[strategies.tolist().index(strategy)]
|
@@ -178,15 +187,15 @@ def plot_results(exp_data_df):
|
|
178 |
)
|
179 |
fig.add_trace(mean_trace)
|
180 |
|
181 |
-
# Add trace for shaded area (standard
|
182 |
fig.add_trace(go.Scatter(
|
183 |
x=list(iterations) + list(iterations[::-1]),
|
184 |
-
y=list(mean_regret +
|
185 |
fill='toself',
|
186 |
fillcolor=mean_trace.line.color.replace('rgb', 'rgba').replace(')', ',0.2)'),
|
187 |
line=dict(color='rgba(255,255,255,0)'),
|
188 |
showlegend=False,
|
189 |
-
name=f'{strategy} (
|
190 |
))
|
191 |
# Add trace for human performance
|
192 |
fig.add_trace(go.Scatter(
|
@@ -226,7 +235,7 @@ def calculate_auc(human_performance_values):
|
|
226 |
return round(auc_value, 4)
|
227 |
|
228 |
# Prediction function - simplified signature by removing unnecessary text params
|
229 |
-
def predict(state, conc1, flow_rate1, voltage1, solvent1, conc2, flow_rate2, voltage2, solvent2):
|
230 |
# Get current results storage from state or initialize if None
|
231 |
if state is None:
|
232 |
results_storage = pd.DataFrame(columns=['Concentration (%w/v)', 'Flow Rate (mL/h)', 'Voltage (kV)', 'Solvent', 'Size (um)', 'Feasible?'])
|
@@ -256,7 +265,7 @@ def predict(state, conc1, flow_rate1, voltage1, solvent1, conc2, flow_rate2, vol
|
|
256 |
# Apply each styling function to its specific column
|
257 |
results_display = results_storage.style\
|
258 |
.map(style_feasible_column, subset=['Feasible?'])\
|
259 |
-
.map(style_size_column, subset=['Size (um)'])\
|
260 |
.format(precision=3)
|
261 |
|
262 |
# Check if user has completed 5 rounds (10 experiments)
|
@@ -268,65 +277,79 @@ def predict(state, conc1, flow_rate1, voltage1, solvent1, conc2, flow_rate2, vol
|
|
268 |
|
269 |
if completed:
|
270 |
# Calculate AUC
|
271 |
-
human_performance = calc_human_performance(results_storage)
|
272 |
auc_value = calculate_auc(human_performance)
|
273 |
-
|
274 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
275 |
usr_level = "randomly playing!"
|
276 |
-
elif
|
277 |
usr_level = "a beginner."
|
278 |
-
elif
|
279 |
usr_level = "an intermediate user."
|
280 |
-
elif
|
281 |
usr_level = "an advanced user."
|
282 |
else:
|
283 |
usr_level = "... come on, you must have cheated (or you are extremely lucky)!"
|
284 |
|
285 |
-
|
|
|
286 |
|
287 |
# Return updated state and UI updates
|
288 |
return (
|
289 |
results_storage,
|
290 |
-
gr.DataFrame(value=
|
291 |
gr.DataFrame(value=results_display, label="Your Results"),
|
292 |
-
plot_results(results_storage),
|
293 |
gr.update(visible=completed), # Show download button when completed
|
294 |
gr.update(value=message, visible=completed), # Show message when completed
|
295 |
gr.update(value=auc_value), # Update AUC value
|
296 |
-
gr.update(visible=completed) # Show result file component
|
|
|
297 |
)
|
298 |
|
299 |
# Reset results function
|
300 |
-
def reset_results(state):
|
301 |
results_storage = pd.DataFrame(columns=['Concentration (%w/v)', 'Flow Rate (mL/h)', 'Voltage (kV)', 'Solvent', 'Size (um)', 'Feasible?'])
|
302 |
# Generate the plot for empty results
|
303 |
-
empty_plot = plot_results(results_storage)
|
304 |
|
305 |
# Apply each styling function to its specific column
|
306 |
styled_results = results_storage.style\
|
307 |
.map(style_feasible_column, subset=['Feasible?'])\
|
308 |
-
.map(style_size_column, subset=['Size (um)'])\
|
309 |
.format(precision=3)
|
310 |
|
311 |
return (
|
312 |
results_storage, # results_state
|
313 |
-
gr.DataFrame(value=
|
314 |
gr.DataFrame(value=styled_results, label="Your Results"), # results_df
|
315 |
empty_plot, # perf_plot
|
316 |
gr.update(visible=False), # download_btn visibility
|
317 |
gr.update(value="", visible=False), # completion_message
|
318 |
gr.update(value=0), # auc_state
|
319 |
-
gr.update(visible=False) # result_file visibility
|
|
|
320 |
)
|
321 |
|
322 |
# Function to prepare results for download
|
323 |
-
def prepare_results_for_download(results):
|
324 |
"""Prepare results dataframe for download and save to CSV"""
|
325 |
if results is None or len(results) == 0:
|
326 |
return None
|
327 |
|
328 |
# Calculate human performance
|
329 |
-
human_performance = calc_human_performance(results)
|
330 |
auc_value = calculate_auc(human_performance)
|
331 |
|
332 |
# Add a summary row with AUC
|
@@ -341,16 +364,17 @@ def prepare_results_for_download(results):
|
|
341 |
|
342 |
# Combine results with summary
|
343 |
combined_df = pd.concat([results, summary_df], ignore_index=True)
|
|
|
344 |
|
345 |
# Save to temporary file
|
346 |
temp_dir = tempfile.gettempdir()
|
347 |
-
output_path = os.path.join(temp_dir, "
|
348 |
combined_df.to_csv(output_path, index=False)
|
349 |
|
350 |
return output_path
|
351 |
|
352 |
# Application description
|
353 |
-
description = "<h3>Welcome, challenger! 🎉</h3><p> If you think you may perform better than <strong>CCBO</strong>, try this interactive game to optimize electrospray!</p><p> Rules are simple:</p> <ul><li>🔍 Examine! The initial experiments are on the right (or below on your phone), remember, your target size is
|
354 |
|
355 |
# Create Gradio interface
|
356 |
with gr.Blocks() as demo:
|
@@ -362,6 +386,14 @@ with gr.Blocks() as demo:
|
|
362 |
with gr.Column():
|
363 |
gr.Markdown("## Human vs CCBO Campaign - Optimize Electrospray")
|
364 |
gr.Markdown(description)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
365 |
|
366 |
with gr.Row():
|
367 |
with gr.Column():
|
@@ -383,16 +415,16 @@ with gr.Blocks() as demo:
|
|
383 |
submit_btn = gr.Button("🚀 Submit", variant="primary")
|
384 |
reset_btn = gr.Button("Reset")
|
385 |
download_btn = gr.Button("📥 Download Results", visible=False)
|
386 |
-
|
387 |
-
# Moved file output component below the buttons
|
388 |
-
result_file = gr.File(label="Download Results CSV", visible=False)
|
389 |
|
390 |
# Add notification component (initially hidden)
|
391 |
completion_message = gr.Markdown(visible=False)
|
392 |
-
|
|
|
|
|
|
|
393 |
# Results display column
|
394 |
with gr.Column():
|
395 |
-
prior_experiments = gr.DataFrame(value=
|
396 |
results_df = gr.DataFrame(label="Your Results")
|
397 |
perf_plot = gr.Plot(label="Performance Comparison")
|
398 |
|
@@ -401,30 +433,44 @@ with gr.Blocks() as demo:
|
|
401 |
fn=predict,
|
402 |
inputs=[
|
403 |
results_state,
|
|
|
404 |
conc1, flow_rate1, voltage1, solvent1,
|
405 |
conc2, flow_rate2, voltage2, solvent2
|
406 |
],
|
407 |
outputs=[
|
408 |
results_state, prior_experiments, results_df, perf_plot,
|
409 |
-
download_btn, completion_message, auc_state, result_file
|
|
|
410 |
]
|
411 |
)
|
412 |
|
413 |
# Connect the reset button to the reset_results function
|
414 |
reset_btn.click(
|
415 |
fn=reset_results,
|
416 |
-
inputs=[results_state],
|
417 |
outputs=[
|
418 |
results_state, prior_experiments, results_df, perf_plot,
|
419 |
-
download_btn, completion_message, auc_state, result_file
|
|
|
420 |
]
|
421 |
)
|
422 |
|
423 |
# Connect download button to file download
|
424 |
download_btn.click(
|
425 |
fn=prepare_results_for_download,
|
426 |
-
inputs=[results_state],
|
427 |
outputs=[result_file]
|
428 |
)
|
429 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
430 |
demo.launch()
|
|
|
16 |
return 'color:white;background-color: lightcoral'
|
17 |
return ''
|
18 |
|
19 |
+
def style_size_column(val, target_size=3.0):
|
20 |
"""Style for the Size column based on proximity to target"""
|
21 |
try:
|
22 |
val_float = float(val)
|
23 |
|
24 |
+
distance = val_float - target_size # Signed distance from target
|
25 |
abs_distance = abs(distance)
|
26 |
|
27 |
# Calculate width percentage based on distance
|
|
|
86 |
exp_record_df['Solvent'] = ['DMAc' if x == 0 else 'CHCl3' for x in exp_record_df['Solvent']]
|
87 |
exp_record_df['Feasible?'] = ['Success' if x == 1 else 'Failed' for x in Y_init[:, 1]]
|
88 |
|
89 |
+
# Replace the static prior_experiments_display with a function
|
90 |
+
def generate_prior_experiments_display(target_size=3.0):
|
91 |
+
"""Generate styled prior experiments display based on target size"""
|
92 |
+
return exp_record_df.style\
|
93 |
+
.map(style_feasible_column, subset=['Feasible?'])\
|
94 |
+
.map(lambda x: style_size_column(x, target_size), subset=['Size (um)'])\
|
95 |
+
.format(precision=3)
|
96 |
+
|
97 |
|
98 |
# Functions for data processing and visualization
|
99 |
+
def import_results(target_size=3):
|
100 |
strategies = ['qEI', 'qEI_vi_mixed_con', 'qEICF_vi_mixed_con', 'rnd']
|
101 |
+
file_name_dict = {
|
102 |
+
'0.5': 'best_distances_0_5.pkl',
|
103 |
+
'3': 'best_distances_3_0.pkl',
|
104 |
+
'22': 'best_distances_22_0.pkl'
|
105 |
+
}
|
106 |
+
# Load results from pickle file based on target size
|
107 |
+
with open(file_name_dict[str(target_size)], 'rb') as f:
|
108 |
best_distances = pickle.load(f)
|
109 |
|
110 |
# vstack all values in best_distances
|
|
|
117 |
best_distances_df_long = pd.melt(best_distances_all_trials_df, id_vars=['strategy', 'trial'], var_name='iteration', value_name='regret')
|
118 |
return best_distances_df_long
|
119 |
|
120 |
+
def calc_human_performance(df, target_size=3.0):
|
121 |
# Make a copy of the dataframe to avoid modifying the original
|
122 |
df_copy = df.copy()
|
123 |
|
124 |
# convert back solvent to 0 and 1
|
125 |
df_copy['Solvent'] = [0 if x == 'DMAc' else 1 for x in df_copy['Solvent']]
|
126 |
|
|
|
127 |
ROUNDS = len(df_copy) // 2
|
128 |
|
129 |
# Ensure all values are numeric
|
|
|
139 |
best_human_distance = []
|
140 |
|
141 |
for iter in range(ROUNDS + 1):
|
142 |
+
Y_distance = -np.abs(Y_human_init[:, 0] - target_size)
|
143 |
best_human_distance.append(np.ma.masked_array(Y_distance, mask=~Y_human_init[:, 1].astype(bool)).max())
|
144 |
|
145 |
# Check if we have more data for this iteration
|
|
|
153 |
|
154 |
return -np.array(best_human_distance)
|
155 |
|
156 |
+
def plot_results(exp_data_df, target_size=3.0):
|
157 |
# Extract human performance
|
158 |
+
best_human_distance = calc_human_performance(exp_data_df, target_size)
|
159 |
|
160 |
# Import results
|
161 |
+
best_distances_df_long = import_results(target_size)
|
162 |
|
163 |
fig = go.Figure()
|
164 |
|
|
|
167 |
for strategy in strategies:
|
168 |
strategy_data = best_distances_df_long[best_distances_df_long['strategy'] == strategy]
|
169 |
|
170 |
+
# Calculate mean and standard error
|
171 |
mean_regret = strategy_data.groupby('iteration')['regret'].mean()
|
172 |
std_regret = strategy_data.groupby('iteration')['regret'].std()
|
173 |
+
# Calculate standard error (SE = SD/√n)
|
174 |
+
n_trials = strategy_data.groupby('iteration')['regret'].count()
|
175 |
+
se_regret = std_regret / np.sqrt(n_trials)
|
176 |
|
177 |
iterations = mean_regret.index
|
178 |
color = px.colors.qualitative.Set2[strategies.tolist().index(strategy)]
|
|
|
187 |
)
|
188 |
fig.add_trace(mean_trace)
|
189 |
|
190 |
+
# Add trace for shaded area (standard error)
|
191 |
fig.add_trace(go.Scatter(
|
192 |
x=list(iterations) + list(iterations[::-1]),
|
193 |
+
y=list(mean_regret + se_regret) + list((mean_regret - se_regret)[::-1]),
|
194 |
fill='toself',
|
195 |
fillcolor=mean_trace.line.color.replace('rgb', 'rgba').replace(')', ',0.2)'),
|
196 |
line=dict(color='rgba(255,255,255,0)'),
|
197 |
showlegend=False,
|
198 |
+
name=f'{strategy} (standard error)'
|
199 |
))
|
200 |
# Add trace for human performance
|
201 |
fig.add_trace(go.Scatter(
|
|
|
235 |
return round(auc_value, 4)
|
236 |
|
237 |
# Prediction function - simplified signature by removing unnecessary text params
|
238 |
+
def predict(state, target_size, conc1, flow_rate1, voltage1, solvent1, conc2, flow_rate2, voltage2, solvent2):
|
239 |
# Get current results storage from state or initialize if None
|
240 |
if state is None:
|
241 |
results_storage = pd.DataFrame(columns=['Concentration (%w/v)', 'Flow Rate (mL/h)', 'Voltage (kV)', 'Solvent', 'Size (um)', 'Feasible?'])
|
|
|
265 |
# Apply each styling function to its specific column
|
266 |
results_display = results_storage.style\
|
267 |
.map(style_feasible_column, subset=['Feasible?'])\
|
268 |
+
.map(lambda x: style_size_column(x, target_size), subset=['Size (um)'])\
|
269 |
.format(precision=3)
|
270 |
|
271 |
# Check if user has completed 5 rounds (10 experiments)
|
|
|
277 |
|
278 |
if completed:
|
279 |
# Calculate AUC
|
280 |
+
human_performance = calc_human_performance(results_storage, target_size)
|
281 |
auc_value = calculate_auc(human_performance)
|
282 |
+
|
283 |
+
# Set CCBO value based on target size
|
284 |
+
if target_size == 3.0:
|
285 |
+
ccbo_value = 1.40
|
286 |
+
elif target_size == 0.5:
|
287 |
+
ccbo_value = 0.92
|
288 |
+
else:
|
289 |
+
ccbo_value = 8.51
|
290 |
+
|
291 |
+
# Calculate performance as a percentage of CCBO value
|
292 |
+
performance_percentage = (auc_value / ccbo_value) * 100
|
293 |
+
|
294 |
+
if performance_percentage > 300:
|
295 |
usr_level = "randomly playing!"
|
296 |
+
elif performance_percentage > 150:
|
297 |
usr_level = "a beginner."
|
298 |
+
elif performance_percentage > 100:
|
299 |
usr_level = "an intermediate user."
|
300 |
+
elif performance_percentage > 65:
|
301 |
usr_level = "an advanced user."
|
302 |
else:
|
303 |
usr_level = "... come on, you must have cheated (or you are extremely lucky)!"
|
304 |
|
305 |
+
|
306 |
+
message = f"🎉 Congratulations! You've completed all 5 rounds. Your performance AUC is ** {auc_value:.2f} ** and CCBO was ** {ccbo_value} **. You seems to be {usr_level} Now you can download your results or click reset to try again!"
|
307 |
|
308 |
# Return updated state and UI updates
|
309 |
return (
|
310 |
results_storage,
|
311 |
+
gr.DataFrame(value=generate_prior_experiments_display(target_size), label="Prior Experiments"),
|
312 |
gr.DataFrame(value=results_display, label="Your Results"),
|
313 |
+
plot_results(results_storage, target_size),
|
314 |
gr.update(visible=completed), # Show download button when completed
|
315 |
gr.update(value=message, visible=completed), # Show message when completed
|
316 |
gr.update(value=auc_value), # Update AUC value
|
317 |
+
gr.update(visible=completed), # Show result file component
|
318 |
+
gr.update(interactive=False if completed else True) # Disable target selection once completed
|
319 |
)
|
320 |
|
321 |
# Reset results function
|
322 |
+
def reset_results(state, target_size):
|
323 |
results_storage = pd.DataFrame(columns=['Concentration (%w/v)', 'Flow Rate (mL/h)', 'Voltage (kV)', 'Solvent', 'Size (um)', 'Feasible?'])
|
324 |
# Generate the plot for empty results
|
325 |
+
empty_plot = plot_results(results_storage, target_size)
|
326 |
|
327 |
# Apply each styling function to its specific column
|
328 |
styled_results = results_storage.style\
|
329 |
.map(style_feasible_column, subset=['Feasible?'])\
|
330 |
+
.map(lambda x: style_size_column(x, target_size), subset=['Size (um)'])\
|
331 |
.format(precision=3)
|
332 |
|
333 |
return (
|
334 |
results_storage, # results_state
|
335 |
+
gr.DataFrame(value=generate_prior_experiments_display(target_size), label="Prior Experiments"), # prior_experiments
|
336 |
gr.DataFrame(value=styled_results, label="Your Results"), # results_df
|
337 |
empty_plot, # perf_plot
|
338 |
gr.update(visible=False), # download_btn visibility
|
339 |
gr.update(value="", visible=False), # completion_message
|
340 |
gr.update(value=0), # auc_state
|
341 |
+
gr.update(visible=False), # result_file visibility
|
342 |
+
gr.update(interactive=True) # Enable target selection
|
343 |
)
|
344 |
|
345 |
# Function to prepare results for download
|
346 |
+
def prepare_results_for_download(results, target_size):
|
347 |
"""Prepare results dataframe for download and save to CSV"""
|
348 |
if results is None or len(results) == 0:
|
349 |
return None
|
350 |
|
351 |
# Calculate human performance
|
352 |
+
human_performance = calc_human_performance(results, target_size)
|
353 |
auc_value = calculate_auc(human_performance)
|
354 |
|
355 |
# Add a summary row with AUC
|
|
|
364 |
|
365 |
# Combine results with summary
|
366 |
combined_df = pd.concat([results, summary_df], ignore_index=True)
|
367 |
+
combined_df = pd.concat([pd.DataFrame([{"Concentration (%w/v)": f"Target size: {target_size} μm"}]), combined_df], ignore_index=True)
|
368 |
|
369 |
# Save to temporary file
|
370 |
temp_dir = tempfile.gettempdir()
|
371 |
+
output_path = os.path.join(temp_dir, f"electrospray_results_{str(target_size).replace('.', '_')}.csv")
|
372 |
combined_df.to_csv(output_path, index=False)
|
373 |
|
374 |
return output_path
|
375 |
|
376 |
# Application description
|
377 |
+
description = "<h3>Welcome, challenger! 🎉</h3><p> If you think you may perform better than <strong>CCBO</strong>, try this interactive game to optimize electrospray!</p><p> Rules are simple:</p> <ul><li>🔍 Examine! The initial experiments are on the right (or below on your phone), remember, your target size is shown at the top</li><li>⚠️ Be aware! Experiment may <u><i><strong>fail</strong></i></u> due to incompatible parameters. You want to avoid those conditions.</li><li>💡 Propose! Set your parameters, you have <strong>2</strong> chances in each round, use them wisely!</li><li>🚀 <strong>Submit</strong> to see the results, reflect and improve your selection!</li><li>🔄 Repeat! Run the process for <strong>5</strong> rounds to see if you can beat CCBO!</li></ul></p><p>Your data will not be stored, so feel free to play again, good luck! 🍀</p><p>Impressed by CCBO? Check our <a href='https://github.com/FrankWanger/CCBO'>implementation</a> and <a href='https://arxiv.org/abs/2411.10471'>paper!</a></p>"
|
378 |
|
379 |
# Create Gradio interface
|
380 |
with gr.Blocks() as demo:
|
|
|
386 |
with gr.Column():
|
387 |
gr.Markdown("## Human vs CCBO Campaign - Optimize Electrospray")
|
388 |
gr.Markdown(description)
|
389 |
+
|
390 |
+
# Add target size selection with new 22.0 option
|
391 |
+
target_size = gr.Radio(
|
392 |
+
[3.0, 0.5, 22.0],
|
393 |
+
label="🎯 Select Target Size (μm)",
|
394 |
+
value=3.0,
|
395 |
+
info="Choose the particle size you want to optimize for"
|
396 |
+
)
|
397 |
|
398 |
with gr.Row():
|
399 |
with gr.Column():
|
|
|
415 |
submit_btn = gr.Button("🚀 Submit", variant="primary")
|
416 |
reset_btn = gr.Button("Reset")
|
417 |
download_btn = gr.Button("📥 Download Results", visible=False)
|
|
|
|
|
|
|
418 |
|
419 |
# Add notification component (initially hidden)
|
420 |
completion_message = gr.Markdown(visible=False)
|
421 |
+
|
422 |
+
# File output component
|
423 |
+
result_file = gr.File(label="Download Results CSV", visible=False)
|
424 |
+
|
425 |
# Results display column
|
426 |
with gr.Column():
|
427 |
+
prior_experiments = gr.DataFrame(value=generate_prior_experiments_display(target_size), label="Prior Experiments")
|
428 |
results_df = gr.DataFrame(label="Your Results")
|
429 |
perf_plot = gr.Plot(label="Performance Comparison")
|
430 |
|
|
|
433 |
fn=predict,
|
434 |
inputs=[
|
435 |
results_state,
|
436 |
+
target_size,
|
437 |
conc1, flow_rate1, voltage1, solvent1,
|
438 |
conc2, flow_rate2, voltage2, solvent2
|
439 |
],
|
440 |
outputs=[
|
441 |
results_state, prior_experiments, results_df, perf_plot,
|
442 |
+
download_btn, completion_message, auc_state, result_file,
|
443 |
+
target_size
|
444 |
]
|
445 |
)
|
446 |
|
447 |
# Connect the reset button to the reset_results function
|
448 |
reset_btn.click(
|
449 |
fn=reset_results,
|
450 |
+
inputs=[results_state, target_size],
|
451 |
outputs=[
|
452 |
results_state, prior_experiments, results_df, perf_plot,
|
453 |
+
download_btn, completion_message, auc_state, result_file,
|
454 |
+
target_size
|
455 |
]
|
456 |
)
|
457 |
|
458 |
# Connect download button to file download
|
459 |
download_btn.click(
|
460 |
fn=prepare_results_for_download,
|
461 |
+
inputs=[results_state, target_size],
|
462 |
outputs=[result_file]
|
463 |
)
|
464 |
|
465 |
+
# When target size changes, reset the application
|
466 |
+
target_size.change(
|
467 |
+
fn=reset_results,
|
468 |
+
inputs=[results_state, target_size],
|
469 |
+
outputs=[
|
470 |
+
results_state, prior_experiments, results_df, perf_plot,
|
471 |
+
download_btn, completion_message, auc_state, result_file,
|
472 |
+
target_size
|
473 |
+
]
|
474 |
+
)
|
475 |
+
|
476 |
demo.launch()
|
best_distances_0_5.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:7eaf04440bd96df457d83d2b72e9a2a355b175b1a36fe8958ceef654a94ade07
|
3 |
+
size 4153
|
best_distances_22_0.pkl
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:3a2360b4669f64295fa30e268a303f2966b4fb7bbdc2fe9ec734ec661835977d
|
3 |
+
size 4153
|
best_distances.pkl → best_distances_3_0.pkl
RENAMED
File without changes
|