C2MV commited on
Commit
6660e8c
1 Parent(s): 1d9c895

Update interface.py

Browse files
Files changed (1) hide show
  1. interface.py +389 -13
interface.py CHANGED
@@ -1,6 +1,6 @@
1
  # interface.py
2
 
3
- from UI import create_interface
4
  from models import BioprocessModel
5
  import io
6
  from PIL import Image
@@ -9,6 +9,7 @@ import numpy as np
9
  import matplotlib.pyplot as plt
10
  import torch
11
  from transformers import AutoTokenizer, AutoModelForCausalLM
 
12
  import copy
13
  from config import DEVICE, MODEL_PATH, MAX_LENGTH, TEMPERATURE
14
 
@@ -49,15 +50,15 @@ def parse_bounds(bounds_str, num_params):
49
 
50
  def process_and_plot(
51
  file,
52
- biomass_equations_list,
53
- biomass_params_list,
54
- biomass_bounds_list,
55
- substrate_equations_list,
56
- substrate_params_list,
57
- substrate_bounds_list,
58
- product_equations_list,
59
- product_params_list,
60
- product_bounds_list,
61
  legend_position,
62
  show_legend,
63
  show_params,
@@ -65,10 +66,385 @@ def process_and_plot(
65
  substrate_eq_count,
66
  product_eq_count
67
  ):
68
- # Implement the function to process data, fit models, generate plots, and get analysis
69
- # Return the plot image and analysis
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  return [image], analysis
71
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  if __name__ == "__main__":
73
- demo = create_interface(process_and_plot)
74
  demo.launch()
 
1
  # interface.py
2
 
3
+ import gradio as gr
4
  from models import BioprocessModel
5
  import io
6
  from PIL import Image
 
9
  import matplotlib.pyplot as plt
10
  import torch
11
  from transformers import AutoTokenizer, AutoModelForCausalLM
12
+ from sympy import symbols, sympify, lambdify
13
  import copy
14
  from config import DEVICE, MODEL_PATH, MAX_LENGTH, TEMPERATURE
15
 
 
50
 
51
  def process_and_plot(
52
  file,
53
+ biomass_eq1, biomass_eq2, biomass_eq3,
54
+ biomass_param1, biomass_param2, biomass_param3,
55
+ biomass_bound1, biomass_bound2, biomass_bound3,
56
+ substrate_eq1, substrate_eq2, substrate_eq3,
57
+ substrate_param1, substrate_param2, substrate_param3,
58
+ substrate_bound1, substrate_bound2, substrate_bound3,
59
+ product_eq1, product_eq2, product_eq3,
60
+ product_param1, product_param2, product_param3,
61
+ product_bound1, product_bound2, product_bound3,
62
  legend_position,
63
  show_legend,
64
  show_params,
 
66
  substrate_eq_count,
67
  product_eq_count
68
  ):
69
+ biomass_eqs = [biomass_eq1, biomass_eq2, biomass_eq3][:biomass_eq_count]
70
+ biomass_params = [biomass_param1, biomass_param2, biomass_param3][:biomass_eq_count]
71
+ biomass_bounds = [biomass_bound1, biomass_bound2, biomass_bound3][:biomass_eq_count]
72
+
73
+ substrate_eqs = [substrate_eq1, substrate_eq2, substrate_eq3][:substrate_eq_count]
74
+ substrate_params = [substrate_param1, substrate_param2, substrate_param3][:substrate_eq_count]
75
+ substrate_bounds = [substrate_bound1, substrate_bound2, substrate_bound3][:substrate_eq_count]
76
+
77
+ product_eqs = [product_eq1, product_eq2, product_eq3][:product_eq_count]
78
+ product_params = [product_param1, product_param2, product_param3][:product_eq_count]
79
+ product_bounds = [product_bound1, product_bound2, product_bound3][:product_eq_count]
80
+
81
+ df = pd.read_excel(file.name)
82
+ time = df['Time'].values
83
+ biomass_data = df['Biomass'].values
84
+ substrate_data = df['Substrate'].values
85
+ product_data = df['Product'].values
86
+
87
+ biomass_results = []
88
+ substrate_results = []
89
+ product_results = []
90
+
91
+ for i in range(len(biomass_eqs)):
92
+ equation = biomass_eqs[i]
93
+ params_str = biomass_params[i]
94
+ bounds_str = biomass_bounds[i]
95
+
96
+ model = BioprocessModel()
97
+ model.set_model('biomass', equation, params_str)
98
+
99
+ params = [param.strip() for param in params_str.split(',')]
100
+ lower_bounds, upper_bounds = parse_bounds(bounds_str, len(params))
101
+
102
+ y_pred = model.fit_model(
103
+ 'biomass', time, biomass_data,
104
+ bounds=(lower_bounds, upper_bounds)
105
+ )
106
+ biomass_results.append({
107
+ 'model': copy.deepcopy(model),
108
+ 'y_pred': y_pred,
109
+ 'equation': equation
110
+ })
111
+
112
+ biomass_model = biomass_results[0]['model']
113
+ X_t = biomass_model.models['biomass']['function']
114
+ biomass_params_values = list(biomass_model.params['biomass'].values())
115
+
116
+ for i in range(len(substrate_eqs)):
117
+ equation = substrate_eqs[i]
118
+ params_str = substrate_params[i]
119
+ bounds_str = substrate_bounds[i]
120
+
121
+ model = BioprocessModel()
122
+
123
+ t_symbol = symbols('t')
124
+ expr_substrate = sympify(equation)
125
+ substrate_params_symbols = symbols([param.strip() for param in params_str.split(',')])
126
+ substrate_func = lambdify(
127
+ (t_symbol, *substrate_params_symbols),
128
+ expr_substrate.subs('X(t)', X_t(t_symbol, *biomass_params_values)),
129
+ 'numpy'
130
+ )
131
+ model.models['substrate'] = {
132
+ 'function': substrate_func,
133
+ 'params': [param.strip() for param in params_str.split(',')]
134
+ }
135
+
136
+ params = model.models['substrate']['params']
137
+ lower_bounds, upper_bounds = parse_bounds(bounds_str, len(params))
138
+
139
+ y_pred = model.fit_model(
140
+ 'substrate', time, substrate_data,
141
+ bounds=(lower_bounds, upper_bounds)
142
+ )
143
+ substrate_results.append({
144
+ 'model': copy.deepcopy(model),
145
+ 'y_pred': y_pred,
146
+ 'equation': equation
147
+ })
148
+
149
+ for i in range(len(product_eqs)):
150
+ equation = product_eqs[i]
151
+ params_str = product_params[i]
152
+ bounds_str = product_bounds[i]
153
+
154
+ model = BioprocessModel()
155
+
156
+ t_symbol = symbols('t')
157
+ expr_product = sympify(equation)
158
+ product_params_symbols = symbols([param.strip() for param in params_str.split(',')])
159
+ product_func = lambdify(
160
+ (t_symbol, *product_params_symbols),
161
+ expr_product.subs('X(t)', X_t(t_symbol, *biomass_params_values)),
162
+ 'numpy'
163
+ )
164
+ model.models['product'] = {
165
+ 'function': product_func,
166
+ 'params': [param.strip() for param in params_str.split(',')]
167
+ }
168
+
169
+ params = model.models['product']['params']
170
+ lower_bounds, upper_bounds = parse_bounds(bounds_str, len(params))
171
+
172
+ y_pred = model.fit_model(
173
+ 'product', time, product_data,
174
+ bounds=(lower_bounds, upper_bounds)
175
+ )
176
+ product_results.append({
177
+ 'model': copy.deepcopy(model),
178
+ 'y_pred': y_pred,
179
+ 'equation': equation
180
+ })
181
+
182
+ fig, axs = plt.subplots(3, 1, figsize=(10, 15))
183
+
184
+ # Biomass Plot
185
+ axs[0].plot(time, biomass_data, 'o', label='Biomass Data')
186
+ for i, result in enumerate(biomass_results):
187
+ axs[0].plot(time, result['y_pred'], '-', label=f'Biomass Model {i+1}')
188
+ axs[0].set_xlabel('Time')
189
+ axs[0].set_ylabel('Biomass')
190
+ if show_legend:
191
+ axs[0].legend(loc=legend_position)
192
+
193
+ # Substrate Plot
194
+ axs[1].plot(time, substrate_data, 'o', label='Substrate Data')
195
+ for i, result in enumerate(substrate_results):
196
+ axs[1].plot(time, result['y_pred'], '-', label=f'Substrate Model {i+1}')
197
+ axs[1].set_xlabel('Time')
198
+ axs[1].set_ylabel('Substrate')
199
+ if show_legend:
200
+ axs[1].legend(loc=legend_position)
201
+
202
+ # Product Plot
203
+ axs[2].plot(time, product_data, 'o', label='Product Data')
204
+ for i, result in enumerate(product_results):
205
+ axs[2].plot(time, result['y_pred'], '-', label=f'Product Model {i+1}')
206
+ axs[2].set_xlabel('Time')
207
+ axs[2].set_ylabel('Product')
208
+ if show_legend:
209
+ axs[2].legend(loc=legend_position)
210
+
211
+ plt.tight_layout()
212
+ buf = io.BytesIO()
213
+ plt.savefig(buf, format='png')
214
+ buf.seek(0)
215
+ image = Image.open(buf)
216
+
217
+ all_results = {
218
+ 'biomass_models': [],
219
+ 'substrate_models': [],
220
+ 'product_models': []
221
+ }
222
+
223
+ for i, result in enumerate(biomass_results):
224
+ model_info = {
225
+ 'model_number': i + 1,
226
+ 'equation': result['equation'],
227
+ 'parameters': result['model'].params['biomass'],
228
+ 'R2': result['model'].r2['biomass'],
229
+ 'RMSE': result['model'].rmse['biomass']
230
+ }
231
+ all_results['biomass_models'].append(model_info)
232
+
233
+ for i, result in enumerate(substrate_results):
234
+ model_info = {
235
+ 'model_number': i + 1,
236
+ 'equation': result['equation'],
237
+ 'parameters': result['model'].params['substrate'],
238
+ 'R2': result['model'].r2['substrate'],
239
+ 'RMSE': result['model'].rmse['substrate']
240
+ }
241
+ all_results['substrate_models'].append(model_info)
242
+
243
+ for i, result in enumerate(product_results):
244
+ model_info = {
245
+ 'model_number': i + 1,
246
+ 'equation': result['equation'],
247
+ 'parameters': result['model'].params['product'],
248
+ 'R2': result['model'].r2['product'],
249
+ 'RMSE': result['model'].rmse['product']
250
+ }
251
+ all_results['product_models'].append(model_info)
252
+
253
+ results_text = "Experimental Results:\n\n"
254
+
255
+ results_text += "Biomass Models:\n"
256
+ for model_info in all_results['biomass_models']:
257
+ results_text += f"""
258
+ Model {model_info['model_number']}:
259
+ Equation: {model_info['equation']}
260
+ Parameters: {model_info['parameters']}
261
+ R²: {model_info['R2']:.4f}
262
+ RMSE: {model_info['RMSE']:.4f}
263
+ """
264
+
265
+ results_text += "\nSubstrate Models:\n"
266
+ for model_info in all_results['substrate_models']:
267
+ results_text += f"""
268
+ Model {model_info['model_number']}:
269
+ Equation: {model_info['equation']}
270
+ Parameters: {model_info['parameters']}
271
+ R²: {model_info['R2']:.4f}
272
+ RMSE: {model_info['RMSE']:.4f}
273
+ """
274
+
275
+ results_text += "\nProduct Models:\n"
276
+ for model_info in all_results['product_models']:
277
+ results_text += f"""
278
+ Model {model_info['model_number']}:
279
+ Equation: {model_info['equation']}
280
+ Parameters: {model_info['parameters']}
281
+ R²: {model_info['R2']:.4f}
282
+ RMSE: {model_info['RMSE']:.4f}
283
+ """
284
+
285
+ prompt = f"""
286
+ You are an expert in bioprocess modeling.
287
+
288
+ Analyze the following experimental results and provide a verdict on the quality of the models, suggesting improvements if necessary.
289
+
290
+ {results_text}
291
+
292
+ Your analysis should be detailed and professional.
293
+ """
294
+ analysis = generate_analysis(prompt)
295
+
296
  return [image], analysis
297
 
298
+ def create_interface():
299
+ with gr.Blocks() as demo:
300
+ gr.Markdown("# Bioprocess Modeling Application with Yi-Coder Integration")
301
+
302
+ file_input = gr.File(label="Upload Excel File")
303
+
304
+ MAX_EQUATIONS = 3
305
+ biomass_equations = []
306
+ biomass_params = []
307
+ biomass_bounds = []
308
+ substrate_equations = []
309
+ substrate_params = []
310
+ substrate_bounds = []
311
+ product_equations = []
312
+ product_params = []
313
+ product_bounds = []
314
+
315
+ def create_model_inputs(model_name, equations_list, params_list, bounds_list):
316
+ with gr.Column():
317
+ gr.Markdown(f"### {model_name} Models")
318
+ for i in range(MAX_EQUATIONS):
319
+ with gr.Row(visible=(i == 0)) as row:
320
+ equation_input = gr.Textbox(
321
+ label=f"{model_name} Model {i+1} Equation",
322
+ placeholder="Enter equation in terms of t and parameters",
323
+ lines=1,
324
+ value="" if i > 0 else "Default equation"
325
+ )
326
+ params_input = gr.Textbox(
327
+ label=f"{model_name} Model {i+1} Parameters",
328
+ placeholder="Comma-separated parameters",
329
+ lines=1,
330
+ value="" if i > 0 else "Parameters"
331
+ )
332
+ bounds_input = gr.Textbox(
333
+ label=f"{model_name} Model {i+1} Bounds",
334
+ placeholder="(lower, upper) for each parameter",
335
+ lines=1
336
+ )
337
+ equations_list.append((row, equation_input))
338
+ params_list.append(params_input)
339
+ bounds_list.append(bounds_input)
340
+ add_btn = gr.Button(f"Add {model_name} Equation")
341
+ remove_btn = gr.Button(f"Remove {model_name} Equation")
342
+ return add_btn, remove_btn
343
+
344
+ with gr.Accordion("Model Definitions", open=True):
345
+ with gr.Row():
346
+ with gr.Column():
347
+ add_biomass_btn, remove_biomass_btn = create_model_inputs(
348
+ "Biomass", biomass_equations, biomass_params, biomass_bounds
349
+ )
350
+ with gr.Column():
351
+ add_substrate_btn, remove_substrate_btn = create_model_inputs(
352
+ "Substrate", substrate_equations, substrate_params, substrate_bounds
353
+ )
354
+ with gr.Column():
355
+ add_product_btn, remove_product_btn = create_model_inputs(
356
+ "Product", product_equations, product_params, product_bounds
357
+ )
358
+
359
+ legend_position = gr.Radio(
360
+ choices=["upper left", "upper right", "lower left", "lower right", "best"],
361
+ label="Legend Position",
362
+ value="best"
363
+ )
364
+ show_legend = gr.Checkbox(label="Show Legend", value=True)
365
+ show_params = gr.Checkbox(label="Show Parameters", value=True)
366
+ simulate_btn = gr.Button("Simulate")
367
+
368
+ with gr.Row():
369
+ output_gallery = gr.Gallery(label="Results", columns=2, height='auto')
370
+ analysis_output = gr.Textbox(label="Yi-Coder Analysis", lines=15)
371
+
372
+ biomass_eq_count = gr.Number(value=1, visible=False)
373
+ substrate_eq_count = gr.Number(value=1, visible=False)
374
+ product_eq_count = gr.Number(value=1, visible=False)
375
+
376
+ def add_equation(equations_list, eq_count):
377
+ eq_count = min(eq_count + 1, MAX_EQUATIONS)
378
+ for i, (row, _) in enumerate(equations_list):
379
+ row.visible = i < eq_count
380
+ return [row.update(visible=row.visible) for row, _ in equations_list], eq_count
381
+
382
+ def remove_equation(equations_list, eq_count):
383
+ eq_count = max(eq_count - 1, 1)
384
+ for i, (row, _) in enumerate(equations_list):
385
+ row.visible = i < eq_count
386
+ return [row.update(visible=row.visible) for row, _ in equations_list], eq_count
387
+
388
+ add_biomass_btn.click(
389
+ fn=lambda eq_count: add_equation(biomass_equations, eq_count),
390
+ inputs=biomass_eq_count,
391
+ outputs=[*[row for row, _ in biomass_equations], biomass_eq_count]
392
+ )
393
+ remove_biomass_btn.click(
394
+ fn=lambda eq_count: remove_equation(biomass_equations, eq_count),
395
+ inputs=biomass_eq_count,
396
+ outputs=[*[row for row, _ in biomass_equations], biomass_eq_count]
397
+ )
398
+
399
+ add_substrate_btn.click(
400
+ fn=lambda eq_count: add_equation(substrate_equations, eq_count),
401
+ inputs=substrate_eq_count,
402
+ outputs=[*[row for row, _ in substrate_equations], substrate_eq_count]
403
+ )
404
+ remove_substrate_btn.click(
405
+ fn=lambda eq_count: remove_equation(substrate_equations, eq_count),
406
+ inputs=substrate_eq_count,
407
+ outputs=[*[row for row, _ in substrate_equations], substrate_eq_count]
408
+ )
409
+
410
+ add_product_btn.click(
411
+ fn=lambda eq_count: add_equation(product_equations, eq_count),
412
+ inputs=product_eq_count,
413
+ outputs=[*[row for row, _ in product_equations], product_eq_count]
414
+ )
415
+ remove_product_btn.click(
416
+ fn=lambda eq_count: remove_equation(product_equations, eq_count),
417
+ inputs=product_eq_count,
418
+ outputs=[*[row for row, _ in product_equations], product_eq_count]
419
+ )
420
+
421
+ simulate_inputs = [
422
+ file_input,
423
+ *[eq_input for row, eq_input in biomass_equations],
424
+ *biomass_params,
425
+ *biomass_bounds,
426
+ *[eq_input for row, eq_input in substrate_equations],
427
+ *substrate_params,
428
+ *substrate_bounds,
429
+ *[eq_input for row, eq_input in product_equations],
430
+ *product_params,
431
+ *product_bounds,
432
+ legend_position,
433
+ show_legend,
434
+ show_params,
435
+ biomass_eq_count,
436
+ substrate_eq_count,
437
+ product_eq_count
438
+ ]
439
+
440
+ simulate_btn.click(
441
+ fn=process_and_plot,
442
+ inputs=simulate_inputs,
443
+ outputs=[output_gallery, analysis_output]
444
+ )
445
+
446
+ return demo
447
+
448
  if __name__ == "__main__":
449
+ demo = create_interface()
450
  demo.launch()