BioRAG / UI.py
C2MV's picture
Upload 3 files
9ee4000 verified
raw
history blame
9.64 kB
# UI.py
import gradio as gr
import numpy as np # Importar numpy para np.inf
def create_interface(process_function_for_button):
with gr.Blocks(theme='gradio/soft') as demo: # Usar un theme común de Gradio
gr.Markdown("# Modelado de Bioprocesos con Ecuaciones Personalizadas y Análisis por IA")
with gr.Row():
with gr.Column(scale=2):
gr.Markdown("### Carga de Datos y Configuración General")
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' # String value, esto está bien
)
with gr.Column(scale=1):
gr.Markdown("### Conteo de Ecuaciones a Probar")
# Asegurar que los valores son numéricos y dentro del rango
biomass_eq_count_ui = gr.Number(label="Biomasa (1-3)", value=1, minimum=1, maximum=3, step=1, precision=0)
substrate_eq_count_ui = gr.Number(label="Sustrato (1-3)", value=1, minimum=1, maximum=3, step=1, precision=0)
product_eq_count_ui = gr.Number(label="Producto (1-3)", value=1, minimum=1, maximum=3, step=1, precision=0)
# --- Sección de Biomasa ---
with gr.Accordion("Ecuaciones y Parámetros de Biomasa", open=True):
with gr.Row():
with gr.Column(): # Columna 1 siempre visible
biomass_eq1_ui = gr.Textbox(label="Ecuación de Biomasa 1", value="Xm * (1 - exp(-um * (t - t_lag)))", lines=2, placeholder="Ej: Xm * (1 - exp(-um * (t - t_lag)))")
biomass_param1_ui = gr.Textbox(label="Parámetros Biomasa 1", value="Xm, um, t_lag", info="Nombres, coma sep. 't' para tiempo. 'X_val' para X(t) en S/P.")
biomass_bound1_ui = gr.Textbox(label="Límites Biomasa 1", value="(0, np.inf), (0, np.inf), (0, np.inf)", info="Formato: (low,high). Use np.inf o None.")
# Definir Columnas 2 y 3 fuera del `with` si se manipula su visibilidad programáticamente
biomass_col2_container = gr.Column(visible=False)
with biomass_col2_container:
biomass_eq2_ui = gr.Textbox(label="Ecuación de Biomasa 2", value="X0 * exp(um * t)", lines=2)
biomass_param2_ui = gr.Textbox(label="Parámetros Biomasa 2", value="X0, um")
biomass_bound2_ui = gr.Textbox(label="Límites Biomasa 2", value="(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 de Biomasa 3", lines=2, value="") # Explicit empty string
biomass_param3_ui = gr.Textbox(label="Parámetros Biomasa 3", value="")
biomass_bound3_ui = gr.Textbox(label="Límites Biomasa 3", value="")
# --- Sección de Sustrato ---
with gr.Accordion("Ecuaciones y Parámetros de Sustrato", open=True):
gr.Markdown("Para Sustrato/Producto, usa `X_val` para X(t). Ejemplo: `S0 - (X_val / YXS)` donde YXS es un parámetro.")
with gr.Row():
with gr.Column():
substrate_eq1_ui = gr.Textbox(label="Ecuación de 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 de Sustrato 2", lines=2, value="")
substrate_param2_ui = gr.Textbox(label="Parámetros Sustrato 2", value="")
substrate_bound2_ui = gr.Textbox(label="Límites Sustrato 2", value="")
substrate_col3_container = gr.Column(visible=False)
with substrate_col3_container:
substrate_eq3_ui = gr.Textbox(label="Ecuación de Sustrato 3", lines=2, value="")
substrate_param3_ui = gr.Textbox(label="Parámetros Sustrato 3", value="")
substrate_bound3_ui = gr.Textbox(label="Límites Sustrato 3", value="")
# --- Sección de Producto ---
with gr.Accordion("Ecuaciones y Parámetros de Producto", open=True):
with gr.Row():
with gr.Column():
product_eq1_ui = gr.Textbox(label="Ecuación de 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 de Producto 2", lines=2, value="")
product_param2_ui = gr.Textbox(label="Parámetros Producto 2", value="")
product_bound2_ui = gr.Textbox(label="Límites Producto 2", value="")
product_col3_container = gr.Column(visible=False)
with product_col3_container:
product_eq3_ui = gr.Textbox(label="Ecuación de Producto 3", lines=2, value="")
product_param3_ui = gr.Textbox(label="Parámetros Producto 3", value="")
product_bound3_ui = gr.Textbox(label="Límites Producto 3", value="")
# Lógica para mostrar/ocultar campos de ecuación dinámicamente
def update_eq_visibility(count_value):
# count_value es float si viene de gr.Number, convertir a int
count = int(count_value)
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", variant="primary", scale=1)
gr.Markdown("## Resultados del Análisis")
with gr.Row():
image_output = gr.Image(label="Gráfico Generado", type="pil", scale=2, show_download_button=True, height=600) # Ajustar altura
with gr.Column(scale=3):
analysis_output = gr.Markdown(label="Análisis del Modelo por IA") # Usar Markdown para mejor formato
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
)
# Inicializar visibilidad usando demo.load para que se aplique al cargar la UI
def set_initial_visibility_on_load_wrapper(b_c, s_c, p_c):
# Convertir a int, ya que el valor inicial de gr.Number puede ser float
b_c_int, s_c_int, p_c_int = int(b_c), int(s_c), int(p_c)
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