C2MV commited on
Commit
9ee4000
·
verified ·
1 Parent(s): 27d09eb

Upload 3 files

Browse files
Files changed (3) hide show
  1. UI.py +68 -50
  2. app.py +9 -9
  3. requirements.txt +4 -1
UI.py CHANGED
@@ -1,44 +1,52 @@
1
  # UI.py
2
  import gradio as gr
 
3
 
4
  def create_interface(process_function_for_button):
5
- with gr.Blocks(theme='upsatwal/mlsc_tiet') as demo:
6
  gr.Markdown("# Modelado de Bioprocesos con Ecuaciones Personalizadas y Análisis por IA")
7
 
8
  with gr.Row():
9
  with gr.Column(scale=2):
10
  gr.Markdown("### Carga de Datos y Configuración General")
11
  file_input = gr.File(label="Subir archivo Excel (.xlsx)", file_types=[".xlsx"])
 
12
  show_legend_ui = gr.Checkbox(label="Mostrar leyenda en gráficos", value=True)
13
  show_params_ui = gr.Checkbox(label="Mostrar parámetros ajustados en gráficos", value=True)
14
  legend_position_ui = gr.Dropdown(
15
  label="Posición de la leyenda",
16
  choices=['best', 'upper right', 'upper left', 'lower right', 'lower left', 'center left', 'center right', 'lower center', 'upper center', 'center'],
17
- value='best'
18
  )
19
  with gr.Column(scale=1):
20
  gr.Markdown("### Conteo de Ecuaciones a Probar")
21
- biomass_eq_count_ui = gr.Number(label="Biomasa (1-3)", value=1, minimum=1, maximum=3, precision=0, step=1)
22
- substrate_eq_count_ui = gr.Number(label="Sustrato (1-3)", value=1, minimum=1, maximum=3, precision=0, step=1)
23
- product_eq_count_ui = gr.Number(label="Producto (1-3)", value=1, minimum=1, maximum=3, precision=0, step=1)
 
24
 
 
25
  with gr.Accordion("Ecuaciones y Parámetros de Biomasa", open=True):
26
  with gr.Row():
27
- with gr.Column():
28
  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)))")
29
- biomass_param1_ui = gr.Textbox(label="Parámetros Biomasa 1", value="Xm, um, t_lag", info="Nombres de parámetros, coma sep. Use 't' para tiempo. 'X_val' para X(t) en S/P.")
30
- biomass_bound1_ui = gr.Textbox(label="Límites Biomasa 1", value="(0, np.inf), (0, np.inf), (0, np.inf)", info="Formato: (low,high) para cada param. Use np.inf.")
31
- biomass_col2 = gr.Column(visible=False) # Columna para la segunda ecuación de biomasa
32
- with biomass_col2: # Contenido de la columna 2
 
 
33
  biomass_eq2_ui = gr.Textbox(label="Ecuación de Biomasa 2", value="X0 * exp(um * t)", lines=2)
34
  biomass_param2_ui = gr.Textbox(label="Parámetros Biomasa 2", value="X0, um")
35
  biomass_bound2_ui = gr.Textbox(label="Límites Biomasa 2", value="(0, np.inf), (0, np.inf)")
36
- biomass_col3 = gr.Column(visible=False) # Columna para la tercera ecuación de biomasa
37
- with biomass_col3: # Contenido de la columna 3
38
- biomass_eq3_ui = gr.Textbox(label="Ecuación de Biomasa 3", lines=2)
39
- biomass_param3_ui = gr.Textbox(label="Parámetros Biomasa 3")
40
- biomass_bound3_ui = gr.Textbox(label="Límites Biomasa 3")
 
41
 
 
42
  with gr.Accordion("Ecuaciones y Parámetros de Sustrato", open=True):
43
  gr.Markdown("Para Sustrato/Producto, usa `X_val` para X(t). Ejemplo: `S0 - (X_val / YXS)` donde YXS es un parámetro.")
44
  with gr.Row():
@@ -46,48 +54,56 @@ def create_interface(process_function_for_button):
46
  substrate_eq1_ui = gr.Textbox(label="Ecuación de Sustrato 1", value="S0 - (X_val / YXS) - mS * t", lines=2)
47
  substrate_param1_ui = gr.Textbox(label="Parámetros Sustrato 1", value="S0, YXS, mS")
48
  substrate_bound1_ui = gr.Textbox(label="Límites Sustrato 1", value="(0, np.inf), (1e-9, np.inf), (0, np.inf)")
49
- substrate_col2 = gr.Column(visible=False)
50
- with substrate_col2:
51
- substrate_eq2_ui = gr.Textbox(label="Ecuación de Sustrato 2", lines=2)
52
- substrate_param2_ui = gr.Textbox(label="Parámetros Sustrato 2")
53
- substrate_bound2_ui = gr.Textbox(label="Límites Sustrato 2")
54
- substrate_col3 = gr.Column(visible=False)
55
- with substrate_col3:
56
- substrate_eq3_ui = gr.Textbox(label="Ecuación de Sustrato 3", lines=2)
57
- substrate_param3_ui = gr.Textbox(label="Parámetros Sustrato 3")
58
- substrate_bound3_ui = gr.Textbox(label="Límites Sustrato 3")
 
 
59
 
 
60
  with gr.Accordion("Ecuaciones y Parámetros de Producto", open=True):
61
  with gr.Row():
62
  with gr.Column():
63
  product_eq1_ui = gr.Textbox(label="Ecuación de Producto 1", value="P0 + YPX * X_val + mP * t", lines=2)
64
  product_param1_ui = gr.Textbox(label="Parámetros Producto 1", value="P0, YPX, mP")
65
  product_bound1_ui = gr.Textbox(label="Límites Producto 1", value="(0, np.inf), (0, np.inf), (0, np.inf)")
66
- product_col2 = gr.Column(visible=False)
67
- with product_col2:
68
- product_eq2_ui = gr.Textbox(label="Ecuación de Producto 2", lines=2)
69
- product_param2_ui = gr.Textbox(label="Parámetros Producto 2")
70
- product_bound2_ui = gr.Textbox(label="Límites Producto 2")
71
- product_col3 = gr.Column(visible=False)
72
- with product_col3:
73
- product_eq3_ui = gr.Textbox(label="Ecuación de Producto 3", lines=2)
74
- product_param3_ui = gr.Textbox(label="Parámetros Producto 3")
75
- product_bound3_ui = gr.Textbox(label="Límites Producto 3")
 
 
76
 
77
- def update_visibility_gradio(count):
 
 
 
78
  return gr.update(visible=count >= 2), gr.update(visible=count >= 3)
79
 
80
- biomass_eq_count_ui.change(fn=update_visibility_gradio, inputs=biomass_eq_count_ui, outputs=[biomass_col2, biomass_col3])
81
- substrate_eq_count_ui.change(fn=update_visibility_gradio, inputs=substrate_eq_count_ui, outputs=[substrate_col2, substrate_col3])
82
- product_eq_count_ui.change(fn=update_visibility_gradio, inputs=product_eq_count_ui, outputs=[product_col2, product_col3])
83
 
84
  submit_button = gr.Button("Procesar y Analizar", variant="primary", scale=1)
85
 
86
  gr.Markdown("## Resultados del Análisis")
87
  with gr.Row():
88
- image_output = gr.Image(label="Gráfico Generado", type="pil", width=600, height=900, scale=2, show_download_button=True)
89
  with gr.Column(scale=3):
90
- analysis_output = gr.Markdown(label="Análisis del Modelo por IA")
91
 
92
  all_inputs_for_button = [
93
  file_input,
@@ -116,19 +132,21 @@ def create_interface(process_function_for_button):
116
  )
117
 
118
  # Inicializar visibilidad usando demo.load para que se aplique al cargar la UI
119
- def set_initial_visibility_on_load(b_c, s_c, p_c):
120
- b_vis2_update, b_vis3_update = update_visibility_gradio(b_c)
121
- s_vis2_update, s_vis3_update = update_visibility_gradio(s_c)
122
- p_vis2_update, p_vis3_update = update_visibility_gradio(p_c)
123
- return b_vis2_update, b_vis3_update, s_vis2_update, s_vis3_update, p_vis2_update, p_vis3_update
 
 
124
 
125
  demo.load(
126
- fn=set_initial_visibility_on_load,
127
  inputs=[biomass_eq_count_ui, substrate_eq_count_ui, product_eq_count_ui],
128
  outputs=[
129
- biomass_col2, biomass_col3,
130
- substrate_col2, substrate_col3,
131
- product_col2, product_col3
132
  ]
133
  )
134
  return demo
 
1
  # UI.py
2
  import gradio as gr
3
+ import numpy as np # Importar numpy para np.inf
4
 
5
  def create_interface(process_function_for_button):
6
+ with gr.Blocks(theme='gradio/soft') as demo: # Usar un theme común de Gradio
7
  gr.Markdown("# Modelado de Bioprocesos con Ecuaciones Personalizadas y Análisis por IA")
8
 
9
  with gr.Row():
10
  with gr.Column(scale=2):
11
  gr.Markdown("### Carga de Datos y Configuración General")
12
  file_input = gr.File(label="Subir archivo Excel (.xlsx)", file_types=[".xlsx"])
13
+
14
  show_legend_ui = gr.Checkbox(label="Mostrar leyenda en gráficos", value=True)
15
  show_params_ui = gr.Checkbox(label="Mostrar parámetros ajustados en gráficos", value=True)
16
  legend_position_ui = gr.Dropdown(
17
  label="Posición de la leyenda",
18
  choices=['best', 'upper right', 'upper left', 'lower right', 'lower left', 'center left', 'center right', 'lower center', 'upper center', 'center'],
19
+ value='best' # String value, esto está bien
20
  )
21
  with gr.Column(scale=1):
22
  gr.Markdown("### Conteo de Ecuaciones a Probar")
23
+ # Asegurar que los valores son numéricos y dentro del rango
24
+ biomass_eq_count_ui = gr.Number(label="Biomasa (1-3)", value=1, minimum=1, maximum=3, step=1, precision=0)
25
+ substrate_eq_count_ui = gr.Number(label="Sustrato (1-3)", value=1, minimum=1, maximum=3, step=1, precision=0)
26
+ product_eq_count_ui = gr.Number(label="Producto (1-3)", value=1, minimum=1, maximum=3, step=1, precision=0)
27
 
28
+ # --- Sección de Biomasa ---
29
  with gr.Accordion("Ecuaciones y Parámetros de Biomasa", open=True):
30
  with gr.Row():
31
+ with gr.Column(): # Columna 1 siempre visible
32
  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)))")
33
+ 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.")
34
+ 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.")
35
+
36
+ # Definir Columnas 2 y 3 fuera del `with` si se manipula su visibilidad programáticamente
37
+ biomass_col2_container = gr.Column(visible=False)
38
+ with biomass_col2_container:
39
  biomass_eq2_ui = gr.Textbox(label="Ecuación de Biomasa 2", value="X0 * exp(um * t)", lines=2)
40
  biomass_param2_ui = gr.Textbox(label="Parámetros Biomasa 2", value="X0, um")
41
  biomass_bound2_ui = gr.Textbox(label="Límites Biomasa 2", value="(0, np.inf), (0, np.inf)")
42
+
43
+ biomass_col3_container = gr.Column(visible=False)
44
+ with biomass_col3_container:
45
+ biomass_eq3_ui = gr.Textbox(label="Ecuación de Biomasa 3", lines=2, value="") # Explicit empty string
46
+ biomass_param3_ui = gr.Textbox(label="Parámetros Biomasa 3", value="")
47
+ biomass_bound3_ui = gr.Textbox(label="Límites Biomasa 3", value="")
48
 
49
+ # --- Sección de Sustrato ---
50
  with gr.Accordion("Ecuaciones y Parámetros de Sustrato", open=True):
51
  gr.Markdown("Para Sustrato/Producto, usa `X_val` para X(t). Ejemplo: `S0 - (X_val / YXS)` donde YXS es un parámetro.")
52
  with gr.Row():
 
54
  substrate_eq1_ui = gr.Textbox(label="Ecuación de Sustrato 1", value="S0 - (X_val / YXS) - mS * t", lines=2)
55
  substrate_param1_ui = gr.Textbox(label="Parámetros Sustrato 1", value="S0, YXS, mS")
56
  substrate_bound1_ui = gr.Textbox(label="Límites Sustrato 1", value="(0, np.inf), (1e-9, np.inf), (0, np.inf)")
57
+
58
+ substrate_col2_container = gr.Column(visible=False)
59
+ with substrate_col2_container:
60
+ substrate_eq2_ui = gr.Textbox(label="Ecuación de Sustrato 2", lines=2, value="")
61
+ substrate_param2_ui = gr.Textbox(label="Parámetros Sustrato 2", value="")
62
+ substrate_bound2_ui = gr.Textbox(label="Límites Sustrato 2", value="")
63
+
64
+ substrate_col3_container = gr.Column(visible=False)
65
+ with substrate_col3_container:
66
+ substrate_eq3_ui = gr.Textbox(label="Ecuación de Sustrato 3", lines=2, value="")
67
+ substrate_param3_ui = gr.Textbox(label="Parámetros Sustrato 3", value="")
68
+ substrate_bound3_ui = gr.Textbox(label="Límites Sustrato 3", value="")
69
 
70
+ # --- Sección de Producto ---
71
  with gr.Accordion("Ecuaciones y Parámetros de Producto", open=True):
72
  with gr.Row():
73
  with gr.Column():
74
  product_eq1_ui = gr.Textbox(label="Ecuación de Producto 1", value="P0 + YPX * X_val + mP * t", lines=2)
75
  product_param1_ui = gr.Textbox(label="Parámetros Producto 1", value="P0, YPX, mP")
76
  product_bound1_ui = gr.Textbox(label="Límites Producto 1", value="(0, np.inf), (0, np.inf), (0, np.inf)")
77
+
78
+ product_col2_container = gr.Column(visible=False)
79
+ with product_col2_container:
80
+ product_eq2_ui = gr.Textbox(label="Ecuación de Producto 2", lines=2, value="")
81
+ product_param2_ui = gr.Textbox(label="Parámetros Producto 2", value="")
82
+ product_bound2_ui = gr.Textbox(label="Límites Producto 2", value="")
83
+
84
+ product_col3_container = gr.Column(visible=False)
85
+ with product_col3_container:
86
+ product_eq3_ui = gr.Textbox(label="Ecuación de Producto 3", lines=2, value="")
87
+ product_param3_ui = gr.Textbox(label="Parámetros Producto 3", value="")
88
+ product_bound3_ui = gr.Textbox(label="Límites Producto 3", value="")
89
 
90
+ # Lógica para mostrar/ocultar campos de ecuación dinámicamente
91
+ def update_eq_visibility(count_value):
92
+ # count_value es float si viene de gr.Number, convertir a int
93
+ count = int(count_value)
94
  return gr.update(visible=count >= 2), gr.update(visible=count >= 3)
95
 
96
+ biomass_eq_count_ui.change(fn=update_eq_visibility, inputs=biomass_eq_count_ui, outputs=[biomass_col2_container, biomass_col3_container])
97
+ substrate_eq_count_ui.change(fn=update_eq_visibility, inputs=substrate_eq_count_ui, outputs=[substrate_col2_container, substrate_col3_container])
98
+ product_eq_count_ui.change(fn=update_eq_visibility, inputs=product_eq_count_ui, outputs=[product_col2_container, product_col3_container])
99
 
100
  submit_button = gr.Button("Procesar y Analizar", variant="primary", scale=1)
101
 
102
  gr.Markdown("## Resultados del Análisis")
103
  with gr.Row():
104
+ image_output = gr.Image(label="Gráfico Generado", type="pil", scale=2, show_download_button=True, height=600) # Ajustar altura
105
  with gr.Column(scale=3):
106
+ analysis_output = gr.Markdown(label="Análisis del Modelo por IA") # Usar Markdown para mejor formato
107
 
108
  all_inputs_for_button = [
109
  file_input,
 
132
  )
133
 
134
  # Inicializar visibilidad usando demo.load para que se aplique al cargar la UI
135
+ def set_initial_visibility_on_load_wrapper(b_c, s_c, p_c):
136
+ # Convertir a int, ya que el valor inicial de gr.Number puede ser float
137
+ b_c_int, s_c_int, p_c_int = int(b_c), int(s_c), int(p_c)
138
+ b_vis2_upd, b_vis3_upd = update_eq_visibility(b_c_int)
139
+ s_vis2_upd, s_vis3_upd = update_eq_visibility(s_c_int)
140
+ p_vis2_upd, p_vis3_upd = update_eq_visibility(p_c_int)
141
+ return b_vis2_upd, b_vis3_upd, s_vis2_upd, s_vis3_upd, p_vis2_upd, p_vis3_upd
142
 
143
  demo.load(
144
+ fn=set_initial_visibility_on_load_wrapper,
145
  inputs=[biomass_eq_count_ui, substrate_eq_count_ui, product_eq_count_ui],
146
  outputs=[
147
+ biomass_col2_container, biomass_col3_container,
148
+ substrate_col2_container, substrate_col3_container,
149
+ product_col2_container, product_col3_container
150
  ]
151
  )
152
  return demo
app.py CHANGED
@@ -1,8 +1,4 @@
1
  # app.py
2
- import os
3
-
4
- os.system("pip install --upgrade gradio")
5
-
6
  import sys
7
  from pathlib import Path
8
 
@@ -11,15 +7,16 @@ if str(CURRENT_DIR) not in sys.path:
11
  sys.path.insert(0, str(CURRENT_DIR))
12
 
13
  try:
14
- import decorators # Importa tu archivo decorators.py
15
  from UI import create_interface
16
  import interface as app_interface_module
17
  except ImportError as e:
18
  print(f"Error crítico de importación en app.py: {e}. Asegúrate de que todos los archivos .py estén en el mismo directorio o en PYTHONPATH.")
 
19
  sys.exit(1)
20
 
21
 
22
- if decorators.was_real_spaces_gpu_imported(): # Usa la función de decorators.py
23
  print("INFO (app.py): El decorador GPU de 'spaces' parece estar disponible.")
24
  print("INFO (app.py): Se definirá una función dummy decorada para satisfacer el chequeo de Gradio si es necesario.")
25
 
@@ -35,16 +32,19 @@ def main():
35
  demo_instance = create_interface(process_function_for_button=app_interface_module.process_and_plot)
36
 
37
  print("INFO (app.py): Lanzando la interfaz Gradio localmente...")
38
- # Si el error de localhost persiste, prueba con share=True
39
- # Esto es más probable si estás en un entorno contenedorizado incluso para "local"
40
  try:
41
  demo_instance.launch()
42
  except ValueError as ve:
43
- if "shareable link must be created" in str(ve):
44
  print("ADVERTENCIA (app.py): Falló el lanzamiento local directo, intentando con share=True...")
45
  demo_instance.launch(share=True)
46
  else:
 
 
47
  raise ve
 
 
 
48
 
49
 
50
  if __name__ == "__main__":
 
1
  # app.py
 
 
 
 
2
  import sys
3
  from pathlib import Path
4
 
 
7
  sys.path.insert(0, str(CURRENT_DIR))
8
 
9
  try:
10
+ import decorators
11
  from UI import create_interface
12
  import interface as app_interface_module
13
  except ImportError as e:
14
  print(f"Error crítico de importación en app.py: {e}. Asegúrate de que todos los archivos .py estén en el mismo directorio o en PYTHONPATH.")
15
+ print(f"sys.path actual: {sys.path}")
16
  sys.exit(1)
17
 
18
 
19
+ if decorators.was_real_spaces_gpu_imported():
20
  print("INFO (app.py): El decorador GPU de 'spaces' parece estar disponible.")
21
  print("INFO (app.py): Se definirá una función dummy decorada para satisfacer el chequeo de Gradio si es necesario.")
22
 
 
32
  demo_instance = create_interface(process_function_for_button=app_interface_module.process_and_plot)
33
 
34
  print("INFO (app.py): Lanzando la interfaz Gradio localmente...")
 
 
35
  try:
36
  demo_instance.launch()
37
  except ValueError as ve:
38
+ if "shareable link must be created" in str(ve).lower() or "localhost is not accessible" in str(ve).lower():
39
  print("ADVERTENCIA (app.py): Falló el lanzamiento local directo, intentando con share=True...")
40
  demo_instance.launch(share=True)
41
  else:
42
+ # Si es otro ValueError, lo relanzamos para verlo completo
43
+ print(f"Error inesperado de ValueError durante launch(): {ve}")
44
  raise ve
45
+ except Exception as e_launch:
46
+ print(f"Error inesperado durante demo.launch(): {e_launch}")
47
+ raise e_launch
48
 
49
 
50
  if __name__ == "__main__":
requirements.txt CHANGED
@@ -1,4 +1,7 @@
1
- gradio
 
 
 
2
  numpy
3
  pandas
4
  matplotlib
 
1
+ # requirements.txt
2
+ gradio==4.29.0
3
+ # OTRA VERSIÓN ESTABLE RECIENTE DE GRADIO 4.X, por ejemplo, gradio==4.31.0
4
+ # ¡¡NO uses gradio sin especificar versión si te está instalando la 5.x !!
5
  numpy
6
  pandas
7
  matplotlib