C2MV commited on
Commit
6e8da07
1 Parent(s): eb368ef

Update bioprocess_model.py

Browse files
Files changed (1) hide show
  1. bioprocess_model.py +124 -52
bioprocess_model.py CHANGED
@@ -1,52 +1,124 @@
1
- def set_model(self, model_type, equation, params_str):
2
- """
3
- Configura el modelo basado en el tipo, ecuación y parámetros.
4
-
5
- :param model_type: Tipo de modelo ('biomass', 'substrate', 'product')
6
- :param equation: La ecuación como cadena de texto
7
- :param params_str: Cadena de texto con los nombres de los parámetros separados por comas
8
- """
9
- t_symbol = symbols('t')
10
- # Definir 'X' como una función simbólica en sympy
11
- X = Function('X')
12
-
13
- try:
14
- expr = sympify(equation)
15
- except Exception as e:
16
- raise ValueError(f"Error al parsear la ecuación '{equation}': {e}")
17
-
18
- params = [param.strip() for param in params_str.split(',')]
19
- params_symbols = symbols(params)
20
-
21
- # Extraer símbolos utilizados en la expresión
22
- used_symbols = expr.free_symbols
23
- # Convertir símbolos a strings
24
- used_params = [str(s) for s in used_symbols if s != t_symbol]
25
-
26
- # Verificar que todos los parámetros en params_str estén usados en la ecuación
27
- for param in params:
28
- if param not in used_params:
29
- raise ValueError(f"El parámetro '{param}' no se usa en la ecuación '{equation}'.")
30
-
31
- if model_type == 'biomass':
32
- # Biomasa como función de tiempo y parámetros
33
- func_expr = expr
34
- func = lambdify((t_symbol, *params_symbols), func_expr, 'numpy')
35
- self.models['biomass'] = {
36
- 'function': func,
37
- 'params': params
38
- }
39
- elif model_type in ['substrate', 'product']:
40
- # Estos modelos dependen de biomasa, que ya debería estar establecida
41
- if 'biomass' not in self.models:
42
- raise ValueError("Biomasa debe estar configurada antes de Sustrato o Producto.")
43
- biomass_func = self.models['biomass']['function']
44
- # Reemplazar 'X(t)' por la función de biomasa
45
- func_expr = expr.subs('X(t)', biomass_func)
46
- func = lambdify((t_symbol, *params_symbols), func_expr, 'numpy')
47
- self.models[model_type] = {
48
- 'function': func,
49
- 'params': params
50
- }
51
- else:
52
- raise ValueError(f"Tipo de modelo no soportado: {model_type}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # bioprocess_model.py
2
+
3
+ import numpy as np
4
+ import pandas as pd
5
+ import matplotlib.pyplot as plt
6
+ from scipy.optimize import curve_fit
7
+ from sklearn.metrics import mean_squared_error
8
+ from sympy import symbols, lambdify, sympify, Function
9
+
10
+ class BioprocessModel:
11
+ def __init__(self):
12
+ self.params = {}
13
+ self.r2 = {}
14
+ self.rmse = {}
15
+ self.models = {} # Initialize the models dictionary
16
+
17
+ @staticmethod
18
+ def logistic(time, xo, xm, um):
19
+ return (xo * np.exp(um * time)) / (1 - (xo / xm) * (1 - np.exp(um * time)))
20
+
21
+ @staticmethod
22
+ def substrate(time, so, p, q, xo, xm, um):
23
+ return so - (p * xo * ((np.exp(um * time)) / (1 - (xo / xm) * (1 - np.exp(um * time))) - 1)) - \
24
+ (q * (xm / um) * np.log(1 - (xo / xm) * (1 - np.exp(um * time))))
25
+
26
+ @staticmethod
27
+ def product(time, po, alpha, beta, xo, xm, um):
28
+ return po + (alpha * xo * ((np.exp(um * time) / (1 - (xo / xm) * (1 - np.exp(um * time))) - 1))) + \
29
+ (beta * (xm / um) * np.log(1 - (xo / xm) * (1 - np.exp(um * time))))
30
+
31
+ def set_model(self, model_type, equation, params_str):
32
+ """
33
+ Configures the model based on the type, equation, and parameters.
34
+
35
+ :param model_type: Type of the model ('biomass', 'substrate', 'product')
36
+ :param equation: The equation as a string
37
+ :param params_str: Comma-separated string of parameter names
38
+ """
39
+ t_symbol = symbols('t')
40
+ X = Function('X') # Definir 'X(t)' como una función simbólica
41
+
42
+ try:
43
+ expr = sympify(equation)
44
+ except Exception as e:
45
+ raise ValueError(f"Error al parsear la ecuación '{equation}': {e}")
46
+
47
+ params = [param.strip() for param in params_str.split(',')]
48
+ params_symbols = symbols(params)
49
+
50
+ # Extraer símbolos utilizados en la expresión
51
+ used_symbols = expr.free_symbols
52
+ # Convertir símbolos a strings
53
+ used_params = [str(s) for s in used_symbols if s != t_symbol]
54
+
55
+ # Verificar que todos los parámetros en params_str estén usados en la ecuación
56
+ for param in params:
57
+ if param not in used_params:
58
+ raise ValueError(f"El parámetro '{param}' no se usa en la ecuación '{equation}'.")
59
+
60
+ if model_type == 'biomass':
61
+ # Biomasa como función de tiempo y parámetros
62
+ func_expr = expr
63
+ func = lambdify((t_symbol, *params_symbols), func_expr, 'numpy')
64
+ self.models['biomass'] = {
65
+ 'function': func,
66
+ 'params': params
67
+ }
68
+ elif model_type in ['substrate', 'product']:
69
+ # Estos modelos dependen de biomasa, que ya debería estar establecida
70
+ if 'biomass' not in self.models:
71
+ raise ValueError("Biomasa debe estar configurada antes de Sustrato o Producto.")
72
+ biomass_func = self.models['biomass']['function']
73
+ # Reemplazar 'X(t)' por la función de biomasa
74
+ func_expr = expr.subs('X(t)', biomass_func)
75
+ func = lambdify((t_symbol, *params_symbols), func_expr, 'numpy')
76
+ self.models[model_type] = {
77
+ 'function': func,
78
+ 'params': params
79
+ }
80
+ else:
81
+ raise ValueError(f"Tipo de modelo no soportado: {model_type}")
82
+
83
+ def fit_model(self, model_type, time, data, bounds=([-np.inf], [np.inf])):
84
+ """
85
+ Fits the model to the data.
86
+
87
+ :param model_type: Type of the model ('biomass', 'substrate', 'product')
88
+ :param time: Time data
89
+ :param data: Observed data to fit
90
+ :param bounds: Bounds for the parameters
91
+ :return: Predicted data from the model
92
+ """
93
+ if model_type not in self.models:
94
+ raise ValueError(f"Model type '{model_type}' is not set. Please use set_model first.")
95
+
96
+ func = self.models[model_type]['function']
97
+ params = self.models[model_type]['params']
98
+
99
+ # Definir la función de ajuste
100
+ def fit_func(t, *args):
101
+ try:
102
+ y = func(t, *args)
103
+ return y
104
+ except Exception as e:
105
+ raise RuntimeError(f"Error en fit_func: {e}")
106
+
107
+ # Definir una estimación inicial para los parámetros
108
+ p0 = [1.0] * len(params) # Puedes ajustar estos valores según sea necesario
109
+
110
+ try:
111
+ # Definir los límites correctamente
112
+ lower_bounds, upper_bounds = bounds
113
+
114
+ # Ajustar el modelo usando curve_fit con p0
115
+ popt, _ = curve_fit(fit_func, time, data, p0=p0, bounds=(lower_bounds, upper_bounds), maxfev=10000)
116
+
117
+ # Guardar los parámetros ajustados en el modelo
118
+ self.params[model_type] = {param: val for param, val in zip(params, popt)}
119
+ y_pred = fit_func(time, *popt)
120
+ self.r2[model_type] = 1 - (np.sum((data - y_pred) ** 2) / np.sum((data - np.mean(data)) ** 2))
121
+ self.rmse[model_type] = np.sqrt(mean_squared_error(data, y_pred))
122
+ return y_pred
123
+ except Exception as e:
124
+ raise RuntimeError(f"Error while fitting {model_type} model: {str(e)}")