|
|
|
import gradio as gr |
|
import numpy as np |
|
|
|
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) |
|
|
|
|
|
|
|
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") |
|
|
|
|
|
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") |
|
|
|
|
|
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] |
|
|
|
|
|
submit_button.click( |
|
fn=process_function_for_button, |
|
inputs=all_inputs_for_button, |
|
outputs=outputs_for_button, |
|
api_name="process_data" |
|
) |
|
|
|
|
|
|
|
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 |