File size: 10,580 Bytes
3f7e7e6
d3d8124
a622789
d3d8124
3f7e7e6
 
 
 
a622789
3f7e7e6
 
a622789
 
 
3f7e7e6
 
 
 
 
 
 
 
 
 
 
 
a622789
3f7e7e6
 
 
 
a622789
3f7e7e6
 
 
 
a622789
 
3f7e7e6
a622789
3f7e7e6
a622789
 
3f7e7e6
 
 
 
 
a622789
 
 
3f7e7e6
 
 
a622789
 
 
29fefec
a622789
3f7e7e6
a622789
3f7e7e6
 
a622789
3f7e7e6
a622789
3f7e7e6
 
 
a622789
 
 
3f7e7e6
 
 
a622789
 
 
3f7e7e6
a622789
3f7e7e6
a622789
3f7e7e6
 
a622789
3f7e7e6
 
 
 
 
a622789
 
 
3f7e7e6
 
 
a622789
 
 
3f7e7e6
 
 
a622789
3f7e7e6
a622789
3f7e7e6
d3d8124
3f7e7e6
 
 
d3d8124
3f7e7e6
d3d8124
3f7e7e6
 
a622789
3f7e7e6
 
d3d8124
3f7e7e6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
06ccd11
 
3f7e7e6
a622789
3f7e7e6
 
06ccd11
3f7e7e6
06ccd11
 
3f7e7e6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227fa34
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# UI.py
import gradio as gr
import numpy as np # Necesario para np.inf

def create_interface(process_function_for_button):
    """
    Crea la interfaz de usuario completa para el modelado de bioprocesos.
    """
    with gr.Blocks(theme='gradio/soft') as demo:
        gr.Markdown("# Modelado de Bioprocesos con Ecuaciones Personalizadas y Análisis por IA")
        gr.Markdown(
            "Sube un archivo Excel (columnas: 'Tiempo', 'Biomasa', 'Sustrato', 'Producto'). "
            "Ingresa ecuaciones (usa 't' para tiempo; 'X_val' para X(t) en S/P), "
            "parámetros y límites. El sistema ajustará los modelos y un LLM analizará los resultados."
        )

        with gr.Row():
            with gr.Column(scale=2):
                gr.Markdown("### 1. Carga de Datos y Configuración General del Gráfico")
                file_input = gr.File(label="Subir archivo Excel (.xlsx)", file_types=[".xlsx"])
                
                show_legend_ui = gr.Checkbox(label="Mostrar leyenda en gráficos", value=True)
                show_params_ui = gr.Checkbox(label="Mostrar parámetros ajustados en gráficos", value=True)
                legend_position_ui = gr.Dropdown(
                    label="Posición de la leyenda",
                    choices=['best', 'upper right', 'upper left', 'lower right', 'lower left', 'center left', 'center right', 'lower center', 'upper center', 'center'],
                    value='best',
                    type="value" 
                )
            with gr.Column(scale=1):
                gr.Markdown("### 2. Conteo de Ecuaciones a Probar")
                gr.Markdown("Define cuántas ecuaciones diferentes probar para cada componente (1-3).")
                biomass_eq_count_ui = gr.Number(label="Ecuaciones de Biomasa:", value=1.0, minimum=1.0, maximum=3.0, step=1.0, precision=0)
                substrate_eq_count_ui = gr.Number(label="Ecuaciones de Sustrato:", value=1.0, minimum=1.0, maximum=3.0, step=1.0, precision=0)
                product_eq_count_ui = gr.Number(label="Ecuaciones de Producto:", value=1.0, minimum=1.0, maximum=3.0, step=1.0, precision=0)

        # --- Contenedores para campos dinámicos ---
        # Biomasa
        with gr.Accordion("3. Definición de Modelos de Biomasa", open=True):
            gr.Markdown("Ecuación (ej: `Xm*(1 - exp(-um*(t - t_lag)))`), Parámetros (ej: `Xm, um, t_lag`), Límites (ej: `(0, np.inf), (0, 5), (0, 100)`).")
            with gr.Row():
                with gr.Column():
                    biomass_eq1_ui = gr.Textbox(label="Ecuación Biomasa 1", value="Xm * (1 - exp(-um * (t - t_lag)))", lines=2)
                    biomass_param1_ui = gr.Textbox(label="Parámetros Biomasa 1", value="Xm, um, t_lag")
                    biomass_bound1_ui = gr.Textbox(label="Límites Biomasa 1", value="(0, np.inf), (0, np.inf), (0, np.inf)")
                
                biomass_col2_container = gr.Column(visible=False) 
                with biomass_col2_container:
                    biomass_eq2_ui = gr.Textbox(label="Ecuación Biomasa 2", value="", lines=2, placeholder="Opcional: X0 * exp(um * t)")
                    biomass_param2_ui = gr.Textbox(label="Parámetros Biomasa 2", value="", placeholder="Opcional: X0, um")
                    biomass_bound2_ui = gr.Textbox(label="Límites Biomasa 2", value="", placeholder="Opcional: (0, np.inf), (0, np.inf)")
                
                biomass_col3_container = gr.Column(visible=False)
                with biomass_col3_container:
                    biomass_eq3_ui = gr.Textbox(label="Ecuación Biomasa 3", lines=2, value="", placeholder="Opcional")
                    biomass_param3_ui = gr.Textbox(label="Parámetros Biomasa 3", value="", placeholder="Opcional")
                    biomass_bound3_ui = gr.Textbox(label="Límites Biomasa 3", value="", placeholder="Opcional")
        
        # Sustrato
        with gr.Accordion("4. Definición de Modelos de Sustrato", open=True):
            gr.Markdown("Usa `X_val` para X(t) si es necesario. Ej: `S0 - (X_val / YXS)`.")
            with gr.Row():
                with gr.Column():
                    substrate_eq1_ui = gr.Textbox(label="Ecuación Sustrato 1", value="S0 - (X_val / YXS) - mS * t", lines=2)
                    substrate_param1_ui = gr.Textbox(label="Parámetros Sustrato 1", value="S0, YXS, mS")
                    substrate_bound1_ui = gr.Textbox(label="Límites Sustrato 1", value="(0, np.inf), (1e-9, np.inf), (0, np.inf)")
                
                substrate_col2_container = gr.Column(visible=False)
                with substrate_col2_container:
                    substrate_eq2_ui = gr.Textbox(label="Ecuación Sustrato 2", lines=2, value="", placeholder="Opcional")
                    substrate_param2_ui = gr.Textbox(label="Parámetros Sustrato 2", value="", placeholder="Opcional")
                    substrate_bound2_ui = gr.Textbox(label="Límites Sustrato 2", value="", placeholder="Opcional")
                
                substrate_col3_container = gr.Column(visible=False)
                with substrate_col3_container:
                    substrate_eq3_ui = gr.Textbox(label="Ecuación Sustrato 3", lines=2, value="", placeholder="Opcional")
                    substrate_param3_ui = gr.Textbox(label="Parámetros Sustrato 3", value="", placeholder="Opcional")
                    substrate_bound3_ui = gr.Textbox(label="Límites Sustrato 3", value="", placeholder="Opcional")

        # Producto
        with gr.Accordion("5. Definición de Modelos de Producto", open=True):
            gr.Markdown("Usa `X_val` para X(t) si es necesario. Ej: `P0 + YPX * X_val`.")
            with gr.Row():
                with gr.Column():
                    product_eq1_ui = gr.Textbox(label="Ecuación Producto 1", value="P0 + YPX * X_val + mP * t", lines=2)
                    product_param1_ui = gr.Textbox(label="Parámetros Producto 1", value="P0, YPX, mP")
                    product_bound1_ui = gr.Textbox(label="Límites Producto 1", value="(0, np.inf), (0, np.inf), (0, np.inf)")
                
                product_col2_container = gr.Column(visible=False)
                with product_col2_container:
                    product_eq2_ui = gr.Textbox(label="Ecuación Producto 2", lines=2, value="", placeholder="Opcional")
                    product_param2_ui = gr.Textbox(label="Parámetros Producto 2", value="", placeholder="Opcional")
                    product_bound2_ui = gr.Textbox(label="Límites Producto 2", value="", placeholder="Opcional")
                
                product_col3_container = gr.Column(visible=False)
                with product_col3_container:
                    product_eq3_ui = gr.Textbox(label="Ecuación Producto 3", lines=2, value="", placeholder="Opcional")
                    product_param3_ui = gr.Textbox(label="Parámetros Producto 3", value="", placeholder="Opcional")
                    product_bound3_ui = gr.Textbox(label="Límites Producto 3", value="", placeholder="Opcional")

        def update_eq_visibility(count_value):
            try:
                count = int(float(count_value)) if count_value is not None else 0
            except ValueError:
                count = 0 
            return gr.update(visible=count >= 2), gr.update(visible=count >= 3)

        biomass_eq_count_ui.change(fn=update_eq_visibility, inputs=biomass_eq_count_ui, outputs=[biomass_col2_container, biomass_col3_container])
        substrate_eq_count_ui.change(fn=update_eq_visibility, inputs=substrate_eq_count_ui, outputs=[substrate_col2_container, substrate_col3_container])
        product_eq_count_ui.change(fn=update_eq_visibility, inputs=product_eq_count_ui, outputs=[product_col2_container, product_col3_container])
        
        submit_button = gr.Button("Procesar y Analizar Modelos", variant="primary", scale=1, elem_id="submit_button_main")
        
        gr.Markdown("## Resultados del Análisis y Modelado")
        with gr.Row():
            image_output = gr.Image(label="Gráfico Generado de Ajustes", type="pil", scale=2, show_download_button=True, height=750, interactive=False)
            with gr.Column(scale=3):
                analysis_output = gr.Markdown(label="Análisis del Modelo por IA")
        
        all_inputs_for_button = [
            file_input,
            biomass_eq1_ui, biomass_eq2_ui, biomass_eq3_ui,
            biomass_param1_ui, biomass_param2_ui, biomass_param3_ui,
            biomass_bound1_ui, biomass_bound2_ui, biomass_bound3_ui,
            substrate_eq1_ui, substrate_eq2_ui, substrate_eq3_ui,
            substrate_param1_ui, substrate_param2_ui, substrate_param3_ui,
            substrate_bound1_ui, substrate_bound2_ui, substrate_bound3_ui,
            product_eq1_ui, product_eq2_ui, product_eq3_ui,
            product_param1_ui, product_param2_ui, product_param3_ui,
            product_bound1_ui, product_bound2_ui, product_bound3_ui,
            legend_position_ui,
            show_legend_ui,
            show_params_ui,
            biomass_eq_count_ui,
            substrate_eq_count_ui,
            product_eq_count_ui
        ]
        outputs_for_button = [image_output, analysis_output]
        # ... (dentro de la función create_interface)
        
        submit_button.click(
            fn=process_function_for_button,
            inputs=all_inputs_for_button,
            outputs=outputs_for_button,
            api_name="process_data"  # ¡DESCOMENTA ESTA LÍNEA!
        )
        
        # ... (resto del código)

        def set_initial_visibility_on_load_wrapper(b_c_val, s_c_val, p_c_val):
            b_c_int = int(float(b_c_val)) if b_c_val is not None else 0
            s_c_int = int(float(s_c_val)) if s_c_val is not None else 0
            p_c_int = int(float(p_c_val)) if p_c_val is not None else 0
            
            b_vis2_upd, b_vis3_upd = update_eq_visibility(b_c_int)
            s_vis2_upd, s_vis3_upd = update_eq_visibility(s_c_int)
            p_vis2_upd, p_vis3_upd = update_eq_visibility(p_c_int)
            
            return b_vis2_upd, b_vis3_upd, s_vis2_upd, s_vis3_upd, p_vis2_upd, p_vis3_upd

        demo.load(
            fn=set_initial_visibility_on_load_wrapper, 
            inputs=[biomass_eq_count_ui, substrate_eq_count_ui, product_eq_count_ui], 
            outputs=[
                biomass_col2_container, biomass_col3_container, 
                substrate_col2_container, substrate_col3_container, 
                product_col2_container, product_col3_container
            ]
        )
    return demo