Update interface.py
Browse files- interface.py +86 -55
interface.py
CHANGED
@@ -23,7 +23,6 @@ model = AutoModelForCausalLM.from_pretrained(model_path)
|
|
23 |
|
24 |
###############################
|
25 |
|
26 |
-
|
27 |
# bioprocess_model.py
|
28 |
|
29 |
import numpy as np
|
@@ -33,6 +32,7 @@ from scipy.integrate import odeint
|
|
33 |
from scipy.optimize import curve_fit
|
34 |
from sklearn.metrics import mean_squared_error
|
35 |
import seaborn as sns
|
|
|
36 |
|
37 |
class BioprocessModel:
|
38 |
def __init__(self):
|
@@ -122,27 +122,38 @@ class BioprocessModel:
|
|
122 |
params = [param.strip() for param in params_str.split(',')]
|
123 |
params_symbols = symbols(params)
|
124 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
125 |
if model_type == 'biomass':
|
126 |
-
#
|
127 |
func_expr = expr
|
128 |
-
func = lambdify(t_symbol, func_expr, 'numpy')
|
129 |
self.models['biomass'] = {
|
130 |
'function': func,
|
131 |
'params': params
|
132 |
}
|
133 |
elif model_type in ['substrate', 'product']:
|
134 |
-
#
|
135 |
if 'biomass' not in self.models:
|
136 |
-
raise ValueError("
|
137 |
biomass_func = self.models['biomass']['function']
|
138 |
-
|
|
|
139 |
func = lambdify((t_symbol, *params_symbols), func_expr, 'numpy')
|
140 |
self.models[model_type] = {
|
141 |
'function': func,
|
142 |
'params': params
|
143 |
}
|
144 |
else:
|
145 |
-
raise ValueError(f"
|
146 |
|
147 |
def fit_model(self, model_type, time, data, bounds=([-np.inf], [np.inf])):
|
148 |
"""
|
@@ -156,8 +167,7 @@ class BioprocessModel:
|
|
156 |
"""
|
157 |
if model_type not in self.models:
|
158 |
raise ValueError(f"Model type '{model_type}' is not set. Please use set_model first.")
|
159 |
-
|
160 |
-
# Función generada por lambdify
|
161 |
func = self.models[model_type]['function']
|
162 |
params = self.models[model_type]['params']
|
163 |
|
@@ -171,18 +181,18 @@ class BioprocessModel:
|
|
171 |
except Exception as e:
|
172 |
print(f"Error in fit_func: {e}")
|
173 |
raise
|
174 |
-
|
175 |
# Depuración: Verificar el número de parámetros que se espera ajustar
|
176 |
print(f"Number of parameters to fit: {len(params)}")
|
177 |
-
|
178 |
try:
|
179 |
# Verifica que curve_fit puede recibir la función correctamente
|
180 |
print(f"Calling curve_fit with time: {time}, data: {data}, bounds: {bounds}")
|
181 |
-
|
182 |
# Intentar ajustar el modelo usando curve_fit
|
183 |
popt, _ = curve_fit(fit_func, time, data, bounds=bounds, maxfev=10000)
|
184 |
print(f"Optimal parameters found: {popt}")
|
185 |
-
|
186 |
# Guardar los parámetros ajustados en el modelo
|
187 |
self.params[model_type] = {param: val for param, val in zip(params, popt)}
|
188 |
y_pred = fit_func(time, *popt)
|
@@ -193,7 +203,6 @@ class BioprocessModel:
|
|
193 |
print(f"Error while fitting {model_type} model: {str(e)}")
|
194 |
raise
|
195 |
|
196 |
-
|
197 |
def plot_combined_results(self, time, biomass, substrate, product,
|
198 |
y_pred_biomass, y_pred_substrate, y_pred_product,
|
199 |
biomass_std=None, substrate_std=None, product_std=None,
|
@@ -227,8 +236,6 @@ class BioprocessModel:
|
|
227 |
fig.tight_layout()
|
228 |
return fig
|
229 |
|
230 |
-
|
231 |
-
|
232 |
###############################
|
233 |
|
234 |
# Decorador GPU aplicado para manejar la ejecución en GPU si está disponible
|
@@ -268,13 +275,16 @@ def generate_analysis(prompt, max_length=1024, device=None):
|
|
268 |
|
269 |
def parse_bounds(bounds_str, num_params):
|
270 |
try:
|
|
|
|
|
271 |
bounds = eval(f"[{bounds_str}]")
|
272 |
if len(bounds) != num_params:
|
273 |
-
raise ValueError
|
274 |
lower_bounds = [b[0] for b in bounds]
|
275 |
upper_bounds = [b[1] for b in bounds]
|
276 |
return lower_bounds, upper_bounds
|
277 |
-
except:
|
|
|
278 |
lower_bounds = [-np.inf] * num_params
|
279 |
upper_bounds = [np.inf] * num_params
|
280 |
return lower_bounds, upper_bounds
|
@@ -335,32 +345,41 @@ def process_and_plot(
|
|
335 |
substrate_results = []
|
336 |
product_results = []
|
337 |
|
|
|
|
|
|
|
338 |
# Ajusta los modelos de Biomasa
|
339 |
for i in range(len(biomass_eqs)):
|
340 |
equation = biomass_eqs[i]
|
341 |
params_str = biomass_params[i]
|
342 |
bounds_str = biomass_bounds[i]
|
343 |
|
344 |
-
|
345 |
-
|
|
|
|
|
346 |
|
347 |
params = [param.strip() for param in params_str.split(',')]
|
348 |
lower_bounds, upper_bounds = parse_bounds(bounds_str, len(params))
|
349 |
|
350 |
-
|
351 |
-
|
352 |
-
|
353 |
-
|
354 |
-
|
355 |
-
|
356 |
-
|
357 |
-
|
358 |
-
|
|
|
|
|
|
|
|
|
359 |
|
360 |
# Usa el primer modelo de biomasa para X(t)
|
361 |
biomass_model = biomass_results[0]['model']
|
362 |
-
biomass_params_values = list(biomass_model.params['biomass'].values())
|
363 |
biomass_func = biomass_model.models['biomass']['function']
|
|
|
364 |
|
365 |
# Ajusta los modelos de Sustrato
|
366 |
for i in range(len(substrate_eqs)):
|
@@ -368,21 +387,27 @@ def process_and_plot(
|
|
368 |
params_str = substrate_params[i]
|
369 |
bounds_str = substrate_bounds[i]
|
370 |
|
371 |
-
|
372 |
-
|
|
|
|
|
373 |
|
374 |
-
params =
|
375 |
lower_bounds, upper_bounds = parse_bounds(bounds_str, len(params))
|
376 |
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
|
|
|
|
|
|
|
|
386 |
|
387 |
# Ajusta los modelos de Producto
|
388 |
for i in range(len(product_eqs)):
|
@@ -390,21 +415,27 @@ def process_and_plot(
|
|
390 |
params_str = product_params[i]
|
391 |
bounds_str = product_bounds[i]
|
392 |
|
393 |
-
|
394 |
-
|
|
|
|
|
395 |
|
396 |
-
params =
|
397 |
lower_bounds, upper_bounds = parse_bounds(bounds_str, len(params))
|
398 |
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
405 |
-
|
406 |
-
|
407 |
-
|
|
|
|
|
|
|
|
|
408 |
|
409 |
# Genera las gráficas
|
410 |
fig, axs = plt.subplots(3, 1, figsize=(10, 15))
|
@@ -458,4 +489,4 @@ Producto:
|
|
458 |
"""
|
459 |
analysis = generate_analysis(prompt, device=device)
|
460 |
|
461 |
-
return
|
|
|
23 |
|
24 |
###############################
|
25 |
|
|
|
26 |
# bioprocess_model.py
|
27 |
|
28 |
import numpy as np
|
|
|
32 |
from scipy.optimize import curve_fit
|
33 |
from sklearn.metrics import mean_squared_error
|
34 |
import seaborn as sns
|
35 |
+
from sympy import symbols, lambdify, sympify
|
36 |
|
37 |
class BioprocessModel:
|
38 |
def __init__(self):
|
|
|
122 |
params = [param.strip() for param in params_str.split(',')]
|
123 |
params_symbols = symbols(params)
|
124 |
|
125 |
+
# Extraer símbolos utilizados en la expresión
|
126 |
+
used_symbols = expr.free_symbols
|
127 |
+
# Convertir símbolos a strings
|
128 |
+
used_params = [str(s) for s in used_symbols if s != t_symbol]
|
129 |
+
|
130 |
+
# Verificar que todos los parámetros en params_str estén usados en la ecuación
|
131 |
+
for param in params:
|
132 |
+
if param not in used_params:
|
133 |
+
raise ValueError(f"El parámetro '{param}' no se usa en la ecuación '{equation}'.")
|
134 |
+
|
135 |
if model_type == 'biomass':
|
136 |
+
# Biomasa como función de tiempo y parámetros
|
137 |
func_expr = expr
|
138 |
+
func = lambdify((t_symbol, *params_symbols), func_expr, 'numpy')
|
139 |
self.models['biomass'] = {
|
140 |
'function': func,
|
141 |
'params': params
|
142 |
}
|
143 |
elif model_type in ['substrate', 'product']:
|
144 |
+
# Estos modelos dependen de biomasa, que ya debería estar establecida
|
145 |
if 'biomass' not in self.models:
|
146 |
+
raise ValueError("Biomasa debe estar configurada antes de Sustrato o Producto.")
|
147 |
biomass_func = self.models['biomass']['function']
|
148 |
+
# Reemplazar 'X(t)' por la función de biomasa
|
149 |
+
func_expr = expr.subs('X(t)', biomass_func)
|
150 |
func = lambdify((t_symbol, *params_symbols), func_expr, 'numpy')
|
151 |
self.models[model_type] = {
|
152 |
'function': func,
|
153 |
'params': params
|
154 |
}
|
155 |
else:
|
156 |
+
raise ValueError(f"Tipo de modelo no soportado: {model_type}")
|
157 |
|
158 |
def fit_model(self, model_type, time, data, bounds=([-np.inf], [np.inf])):
|
159 |
"""
|
|
|
167 |
"""
|
168 |
if model_type not in self.models:
|
169 |
raise ValueError(f"Model type '{model_type}' is not set. Please use set_model first.")
|
170 |
+
|
|
|
171 |
func = self.models[model_type]['function']
|
172 |
params = self.models[model_type]['params']
|
173 |
|
|
|
181 |
except Exception as e:
|
182 |
print(f"Error in fit_func: {e}")
|
183 |
raise
|
184 |
+
|
185 |
# Depuración: Verificar el número de parámetros que se espera ajustar
|
186 |
print(f"Number of parameters to fit: {len(params)}")
|
187 |
+
|
188 |
try:
|
189 |
# Verifica que curve_fit puede recibir la función correctamente
|
190 |
print(f"Calling curve_fit with time: {time}, data: {data}, bounds: {bounds}")
|
191 |
+
|
192 |
# Intentar ajustar el modelo usando curve_fit
|
193 |
popt, _ = curve_fit(fit_func, time, data, bounds=bounds, maxfev=10000)
|
194 |
print(f"Optimal parameters found: {popt}")
|
195 |
+
|
196 |
# Guardar los parámetros ajustados en el modelo
|
197 |
self.params[model_type] = {param: val for param, val in zip(params, popt)}
|
198 |
y_pred = fit_func(time, *popt)
|
|
|
203 |
print(f"Error while fitting {model_type} model: {str(e)}")
|
204 |
raise
|
205 |
|
|
|
206 |
def plot_combined_results(self, time, biomass, substrate, product,
|
207 |
y_pred_biomass, y_pred_substrate, y_pred_product,
|
208 |
biomass_std=None, substrate_std=None, product_std=None,
|
|
|
236 |
fig.tight_layout()
|
237 |
return fig
|
238 |
|
|
|
|
|
239 |
###############################
|
240 |
|
241 |
# Decorador GPU aplicado para manejar la ejecución en GPU si está disponible
|
|
|
275 |
|
276 |
def parse_bounds(bounds_str, num_params):
|
277 |
try:
|
278 |
+
# Reemplazar 'inf' por 'np.inf' si el usuario lo escribió así
|
279 |
+
bounds_str = bounds_str.replace('inf', 'np.inf')
|
280 |
bounds = eval(f"[{bounds_str}]")
|
281 |
if len(bounds) != num_params:
|
282 |
+
raise ValueError("Número de límites no coincide con el número de parámetros.")
|
283 |
lower_bounds = [b[0] for b in bounds]
|
284 |
upper_bounds = [b[1] for b in bounds]
|
285 |
return lower_bounds, upper_bounds
|
286 |
+
except Exception as e:
|
287 |
+
print(f"Error al parsear los límites: {e}. Usando límites por defecto.")
|
288 |
lower_bounds = [-np.inf] * num_params
|
289 |
upper_bounds = [np.inf] * num_params
|
290 |
return lower_bounds, upper_bounds
|
|
|
345 |
substrate_results = []
|
346 |
product_results = []
|
347 |
|
348 |
+
# Inicializar el modelo principal
|
349 |
+
main_model = BioprocessModel()
|
350 |
+
|
351 |
# Ajusta los modelos de Biomasa
|
352 |
for i in range(len(biomass_eqs)):
|
353 |
equation = biomass_eqs[i]
|
354 |
params_str = biomass_params[i]
|
355 |
bounds_str = biomass_bounds[i]
|
356 |
|
357 |
+
try:
|
358 |
+
main_model.set_model('biomass', equation, params_str)
|
359 |
+
except ValueError as ve:
|
360 |
+
raise ValueError(f"Error en la configuración del modelo de biomasa {i+1}: {ve}")
|
361 |
|
362 |
params = [param.strip() for param in params_str.split(',')]
|
363 |
lower_bounds, upper_bounds = parse_bounds(bounds_str, len(params))
|
364 |
|
365 |
+
try:
|
366 |
+
y_pred = main_model.fit_model(
|
367 |
+
'biomass', time, biomass_data,
|
368 |
+
bounds=(lower_bounds, upper_bounds)
|
369 |
+
)
|
370 |
+
biomass_results.append({
|
371 |
+
'model': main_model,
|
372 |
+
'y_pred': y_pred,
|
373 |
+
'equation': equation,
|
374 |
+
'params': main_model.params['biomass']
|
375 |
+
})
|
376 |
+
except Exception as e:
|
377 |
+
raise RuntimeError(f"Error al ajustar el modelo de biomasa {i+1}: {e}")
|
378 |
|
379 |
# Usa el primer modelo de biomasa para X(t)
|
380 |
biomass_model = biomass_results[0]['model']
|
|
|
381 |
biomass_func = biomass_model.models['biomass']['function']
|
382 |
+
biomass_params_values = list(biomass_model.params['biomass'].values())
|
383 |
|
384 |
# Ajusta los modelos de Sustrato
|
385 |
for i in range(len(substrate_eqs)):
|
|
|
387 |
params_str = substrate_params[i]
|
388 |
bounds_str = substrate_bounds[i]
|
389 |
|
390 |
+
try:
|
391 |
+
main_model.set_model('substrate', equation, params_str)
|
392 |
+
except ValueError as ve:
|
393 |
+
raise ValueError(f"Error en la configuración del modelo de sustrato {i+1}: {ve}")
|
394 |
|
395 |
+
params = [param.strip() for param in params_str.split(',')]
|
396 |
lower_bounds, upper_bounds = parse_bounds(bounds_str, len(params))
|
397 |
|
398 |
+
try:
|
399 |
+
y_pred = main_model.fit_model(
|
400 |
+
'substrate', time, substrate_data,
|
401 |
+
bounds=(lower_bounds, upper_bounds)
|
402 |
+
)
|
403 |
+
substrate_results.append({
|
404 |
+
'model': main_model,
|
405 |
+
'y_pred': y_pred,
|
406 |
+
'equation': equation,
|
407 |
+
'params': main_model.params['substrate']
|
408 |
+
})
|
409 |
+
except Exception as e:
|
410 |
+
raise RuntimeError(f"Error al ajustar el modelo de sustrato {i+1}: {e}")
|
411 |
|
412 |
# Ajusta los modelos de Producto
|
413 |
for i in range(len(product_eqs)):
|
|
|
415 |
params_str = product_params[i]
|
416 |
bounds_str = product_bounds[i]
|
417 |
|
418 |
+
try:
|
419 |
+
main_model.set_model('product', equation, params_str)
|
420 |
+
except ValueError as ve:
|
421 |
+
raise ValueError(f"Error en la configuración del modelo de producto {i+1}: {ve}")
|
422 |
|
423 |
+
params = [param.strip() for param in params_str.split(',')]
|
424 |
lower_bounds, upper_bounds = parse_bounds(bounds_str, len(params))
|
425 |
|
426 |
+
try:
|
427 |
+
y_pred = main_model.fit_model(
|
428 |
+
'product', time, product_data,
|
429 |
+
bounds=(lower_bounds, upper_bounds)
|
430 |
+
)
|
431 |
+
product_results.append({
|
432 |
+
'model': main_model,
|
433 |
+
'y_pred': y_pred,
|
434 |
+
'equation': equation,
|
435 |
+
'params': main_model.params['product']
|
436 |
+
})
|
437 |
+
except Exception as e:
|
438 |
+
raise RuntimeError(f"Error al ajustar el modelo de producto {i+1}: {e}")
|
439 |
|
440 |
# Genera las gráficas
|
441 |
fig, axs = plt.subplots(3, 1, figsize=(10, 15))
|
|
|
489 |
"""
|
490 |
analysis = generate_analysis(prompt, device=device)
|
491 |
|
492 |
+
return image, analysis
|