AIdeaText commited on
Commit
b58af47
·
verified ·
1 Parent(s): 9616a51

Update modules/morphosyntax/morphosyntax_interface.py

Browse files
modules/morphosyntax/morphosyntax_interface.py CHANGED
@@ -21,8 +21,8 @@ from .morphosyntax_process import (
21
  POS_COLORS,
22
  POS_TRANSLATIONS
23
  )
24
- from ..utils.widget_utils import generate_unique_key
25
 
 
26
  from ..database.morphosyntax_iterative_mongo_db import (
27
  store_student_morphosyntax_base,
28
  store_student_morphosyntax_iteration,
@@ -37,14 +37,12 @@ logger = logging.getLogger(__name__)
37
 
38
  ###########################################################################
39
  def initialize_arc_analysis_state():
40
- """Inicializa el estado del análisis de arcos y el caché si no existen."""
41
  if 'arc_analysis_state' not in st.session_state:
42
  st.session_state.arc_analysis_state = {
43
- 'base_id': None, # ID del análisis base
44
- 'original_text': '', # Texto original
45
- 'original_analysis': None, # Resultado análisis original
46
- 'iteration_text': '', # Texto de iteración
47
- 'iteration_analysis': None,# Resultado análisis iteración
48
  'analysis_count': 0
49
  }
50
  logger.info("Estado de análisis de arcos inicializado")
@@ -54,89 +52,76 @@ def initialize_arc_analysis_state():
54
  st.session_state.analysis_cache = {}
55
  logger.info("Caché de análisis inicializado")
56
 
57
-
58
  def reset_morpho_state():
59
- """Resetea el estado del análisis morfosintáctico en sesión."""
60
  if 'arc_analysis_state' in st.session_state:
61
  st.session_state.arc_analysis_state = {
62
  'base_id': None,
63
  'original_text': '',
64
- 'original_analysis': None,
65
  'iteration_text': '',
66
- 'iteration_analysis': None,
67
  'analysis_count': 0
68
  }
69
 
70
-
71
  def display_original_analysis(container, analysis, lang_code, morpho_t):
72
- """Muestra el análisis original en el contenedor especificado."""
73
  with container:
74
  st.subheader("Análisis Original")
75
  display_morphosyntax_results(analysis, lang_code, morpho_t)
76
 
77
-
78
  def display_iteration_analysis(container, analysis, lang_code, morpho_t):
79
- """Muestra el análisis de cambios en el contenedor especificado."""
80
  with container:
81
  st.subheader("Análisis de Cambios")
82
  display_morphosyntax_results(analysis, lang_code, morpho_t)
83
 
84
-
85
  def display_arc_diagram(doc, analysis):
86
- """Muestra un diagrama de arco sin título."""
87
  try:
88
  for sent in doc.sents:
89
- svg_html = displacy.render(
90
- sent,
91
- style="dep",
92
- options={
93
- "distance": 100,
94
- "arrow_spacing": 20,
95
- "word_spacing": 30
96
- }
97
- )
98
  # Ajustar tamaño y posición
99
- svg_html = svg_html.replace('height="375"', 'height="200"')
100
- svg_html = re.sub(
101
  r'<svg[^>]*>',
102
  lambda m: m.group(0).replace('height="450"', 'height="300"'),
103
- svg_html
104
  )
105
- svg_html = re.sub(
106
- r'<g [^>]*transform="translate\((\d+),(\d+)\)"',
107
  lambda m: f'<g transform="translate({m.group(1)},50)"',
108
- svg_html
109
  )
110
 
111
  # Envolver en contenedor con estilo
112
- svg_html = f'<div class="arc-diagram-container">{svg_html}</div>'
113
- st.write(svg_html, unsafe_allow_html=True)
114
 
115
  except Exception as e:
116
  logger.error(f"Error en display_arc_diagram: {str(e)}")
117
 
118
-
119
  def cache_analysis_results(key, result):
120
- """Almacena resultados de análisis en caché."""
121
- if not hasattr(st.session_state, 'analysis_cache'):
122
- initialize_arc_analysis_state()
123
  st.session_state.analysis_cache[key] = result
124
  logger.info(f"Resultado almacenado en caché con clave: {key}")
125
 
126
-
127
  def get_cached_analysis(key):
128
- """Recupera resultados de análisis del caché."""
129
- if not hasattr(st.session_state, 'analysis_cache'):
130
- initialize_arc_analysis_state()
131
  return None
132
  return st.session_state.analysis_cache.get(key)
133
 
134
-
135
  def display_morphosyntax_interface(lang_code, nlp_models, morpho_t):
136
- """
137
- Interfaz principal para el análisis morfosintáctico.
138
- Evita resets indebidos y conserva la pestaña activa.
139
- """
140
  try:
141
  # CSS para layout estable
142
  st.markdown("""
@@ -161,65 +146,49 @@ def display_morphosyntax_interface(lang_code, nlp_models, morpho_t):
161
  </style>
162
  """, unsafe_allow_html=True)
163
 
164
- # Inicializar estados de análisis si no existen
165
  initialize_arc_analysis_state()
166
 
167
- # ------------------------------------------------------------------
168
- # Si tuvieras un control de tabs global, puedes comentarlo:
169
- #
170
- # st.session_state.tab_states['morpho_active'] = True
171
- # st.session_state.selected_tab = 1
172
- # ------------------------------------------------------------------
173
-
174
- # Crear subtabs
175
  subtabs = st.tabs([
176
  "Análisis de Diagramas de Arco",
177
  "Análisis de Categorías",
178
  "Análisis Morfológico"
179
  ])
180
 
181
- # -------------------- Subtab 0: Diagramas de Arco --------------------
182
  with subtabs[0]:
183
- # Botón de reset
184
- col1, col2, col3 = st.columns([2, 1, 2])
185
  with col1:
186
  if st.button("Nuevo Análisis", type="secondary", use_container_width=True):
187
  reset_morpho_state()
188
- # Forzar el recálculo limpio
189
- st.rerun()
190
-
191
- # Container principal para análisis base
192
- analysis_container = st.container()
193
- with analysis_container:
194
- # Entrada de texto original
195
- text_input_key = f"original_text_{st.session_state.arc_analysis_state['analysis_count']}"
196
  text_input = st.text_area(
197
- "Texto original",
198
  value=st.session_state.arc_analysis_state.get('original_text', ''),
199
- key=text_input_key,
200
  height=100
201
  )
202
 
203
- # Botón de análisis
204
- col1, col2, col3 = st.columns([2, 1, 2])
205
- with col1:
206
- analyze_button = st.button(
207
- "Analizar Texto",
208
- type="primary",
209
- use_container_width=True
210
- )
211
 
212
  # Procesar texto original
213
  if analyze_button and text_input.strip():
214
  try:
215
- # Realizar análisis base (SpaCy)
216
  doc = nlp_models[lang_code](text_input)
217
  analysis = perform_advanced_morphosyntactic_analysis(
218
  text_input,
219
  nlp_models[lang_code]
220
  )
221
 
222
- # Guardar análisis base en BD y obtener ID
223
  base_id = store_student_morphosyntax_base(
224
  st.session_state.username,
225
  text_input,
@@ -227,44 +196,32 @@ def display_morphosyntax_interface(lang_code, nlp_models, morpho_t):
227
  )
228
 
229
  if base_id:
230
- # Actualizar el estado en session_state
231
- st.session_state.arc_analysis_state.update({
232
- 'base_id': base_id,
233
- 'original_text': text_input,
234
- 'original_analysis': analysis, # guardamos el dict
235
- 'analysis_count': st.session_state.arc_analysis_state['analysis_count'] + 1
236
- })
237
-
238
- # Mostrar diagrama base
239
  display_arc_diagram(doc, analysis)
240
 
241
- # Línea divisora
242
  st.markdown('<hr class="divider">', unsafe_allow_html=True)
243
 
244
- # Área de iteración: usar un formulario
245
- with st.form("iteration_form"):
246
- # Separamos la key para la iteración para que no se sobreescriba
247
- iteration_text_key = f"iteration_text_{st.session_state.arc_analysis_state['analysis_count']}"
248
-
249
- # Mostrar el texto de iteración que tengamos en session_state
250
- iteration_text = st.text_area(
251
- "Texto de iteración",
252
- value=st.session_state.arc_analysis_state.get('iteration_text', text_input),
253
- key=iteration_text_key,
254
- height=100
255
- )
256
-
257
- # Botón de submit en el formulario
258
- col1, col2, col3 = st.columns([2,1,2])
259
- with col1:
260
- submitted = st.form_submit_button(
261
- "Analizar Cambios",
262
- type="primary",
263
- use_container_width=True
264
- )
265
-
266
- # Procesar iteración
267
- if submitted and iteration_text.strip():
268
  try:
269
  doc_iter = nlp_models[lang_code](iteration_text)
270
  analysis_iter = perform_advanced_morphosyntactic_analysis(
@@ -272,22 +229,17 @@ def display_morphosyntax_interface(lang_code, nlp_models, morpho_t):
272
  nlp_models[lang_code]
273
  )
274
 
275
- # Guardar iteración
276
  iteration_id = store_student_morphosyntax_iteration(
277
  st.session_state.username,
278
  base_id,
279
- text_input, # Texto original
280
- iteration_text, # Texto de iteración
281
  analysis_iter['arc_diagrams']
282
  )
283
 
284
  if iteration_id:
285
- # Actualizar el estado de iteración en session_state
286
- st.session_state.arc_analysis_state.update({
287
- 'iteration_text': iteration_text,
288
- 'iteration_analysis': analysis_iter
289
- })
290
- # Mostrar diagrama de iteración
291
  display_arc_diagram(doc_iter, analysis_iter)
292
 
293
  except Exception as e:
@@ -296,61 +248,59 @@ def display_morphosyntax_interface(lang_code, nlp_models, morpho_t):
296
 
297
  except Exception as e:
298
  st.error("Error procesando análisis base")
299
- logger.error(f"Error base: {str(e)}")
300
 
301
- # -------------------- Subtab 1: Análisis de Categorías ----------------
302
  with subtabs[1]:
303
  st.info("Análisis de Categorías en desarrollo...")
304
 
305
- # -------------------- Subtab 2: Análisis Morfológico ------------------
306
  with subtabs[2]:
307
  st.info("Análisis Morfológico en desarrollo...")
308
 
309
  except Exception as e:
310
- st.error("Error en la interfaz de morfosintaxis")
311
  logger.error(f"Error general en la interfaz: {str(e)}")
312
 
313
-
314
  def display_morphosyntax_results(result, lang_code, morpho_t):
315
  """
316
  Muestra solo el diagrama de arco.
317
  Args:
318
  result: Diccionario con el documento procesado y su análisis
319
  lang_code: Código del idioma
320
- morpho_t: Diccionario de traducciones (opcional)
321
  """
322
  if result is None:
323
  return
 
324
  try:
325
  doc = result['doc']
326
  sentences = list(doc.sents)
327
  for i, sent in enumerate(sentences):
328
  try:
329
  st.subheader(f"{morpho_t.get('sentence', 'Sentence')} {i+1}")
330
- svg_html = displacy.render(
331
- sent,
332
- style="dep",
333
- options={
334
- "distance": 100,
335
- "arrow_spacing": 20,
336
- "word_spacing": 30
337
- }
338
- )
339
- svg_html = svg_html.replace('height="375"', 'height="200"')
340
- svg_html = re.sub(
341
  r'<svg[^>]*>',
342
  lambda m: m.group(0).replace('height="450"', 'height="300"'),
343
- svg_html
344
  )
345
- svg_html = re.sub(
346
  r'<g [^>]*transform="translate\((\d+),(\d+)\)"',
347
  lambda m: f'<g transform="translate({m.group(1)},50)"',
348
- svg_html
349
  )
350
- svg_html = f'<div class="arc-diagram-container">{svg_html}</div>'
351
- st.write(svg_html, unsafe_allow_html=True)
352
- except Exception as exc:
353
- logger.error(f"Error mostrando diagrama de la oración {i}: {str(exc)}")
354
  continue
355
  except Exception as e:
356
  logger.error(f"Error en display_morphosyntax_results: {str(e)}")
 
 
21
  POS_COLORS,
22
  POS_TRANSLATIONS
23
  )
 
24
 
25
+ from ..utils.widget_utils import generate_unique_key
26
  from ..database.morphosyntax_iterative_mongo_db import (
27
  store_student_morphosyntax_base,
28
  store_student_morphosyntax_iteration,
 
37
 
38
  ###########################################################################
39
  def initialize_arc_analysis_state():
40
+ """Inicializa el estado del análisis de arcos y el caché si no existen"""
41
  if 'arc_analysis_state' not in st.session_state:
42
  st.session_state.arc_analysis_state = {
43
+ 'base_id': None,
44
+ 'original_text': '',
45
+ 'iteration_text': '',
 
 
46
  'analysis_count': 0
47
  }
48
  logger.info("Estado de análisis de arcos inicializado")
 
52
  st.session_state.analysis_cache = {}
53
  logger.info("Caché de análisis inicializado")
54
 
55
+ ###########################################################################
56
  def reset_morpho_state():
57
+ """Resetea el estado del análisis morfosintáctico"""
58
  if 'arc_analysis_state' in st.session_state:
59
  st.session_state.arc_analysis_state = {
60
  'base_id': None,
61
  'original_text': '',
 
62
  'iteration_text': '',
 
63
  'analysis_count': 0
64
  }
65
 
66
+ ###########################################################################
67
  def display_original_analysis(container, analysis, lang_code, morpho_t):
68
+ """Muestra el análisis original en el contenedor especificado"""
69
  with container:
70
  st.subheader("Análisis Original")
71
  display_morphosyntax_results(analysis, lang_code, morpho_t)
72
 
 
73
  def display_iteration_analysis(container, analysis, lang_code, morpho_t):
74
+ """Muestra el análisis de cambios en el contenedor especificado"""
75
  with container:
76
  st.subheader("Análisis de Cambios")
77
  display_morphosyntax_results(analysis, lang_code, morpho_t)
78
 
 
79
  def display_arc_diagram(doc, analysis):
80
+ """Muestra un diagrama de arco sin título"""
81
  try:
82
  for sent in doc.sents:
83
+ rendered = displacy.render(sent, style="dep", options={
84
+ "distance": 100,
85
+ "arrow_spacing": 20,
86
+ "word_spacing": 30
87
+ })
88
+
 
 
 
89
  # Ajustar tamaño y posición
90
+ rendered = rendered.replace('height="375"', 'height="200"')
91
+ rendered = re.sub(
92
  r'<svg[^>]*>',
93
  lambda m: m.group(0).replace('height="450"', 'height="300"'),
94
+ rendered
95
  )
96
+ rendered = re.sub(
97
+ r'<g [^>]*transform="translate\((\d+),(\d+)\)"',
98
  lambda m: f'<g transform="translate({m.group(1)},50)"',
99
+ rendered
100
  )
101
 
102
  # Envolver en contenedor con estilo
103
+ rendered = f'<div class="arc-diagram-container">{rendered}</div>'
104
+ st.write(rendered, unsafe_allow_html=True)
105
 
106
  except Exception as e:
107
  logger.error(f"Error en display_arc_diagram: {str(e)}")
108
 
109
+ ###########################################################################
110
  def cache_analysis_results(key, result):
111
+ """Almacena resultados de análisis en caché"""
112
+ if 'analysis_cache' not in st.session_state:
113
+ st.session_state.analysis_cache = {}
114
  st.session_state.analysis_cache[key] = result
115
  logger.info(f"Resultado almacenado en caché con clave: {key}")
116
 
 
117
  def get_cached_analysis(key):
118
+ """Recupera resultados de análisis del caché"""
119
+ if 'analysis_cache' not in st.session_state:
 
120
  return None
121
  return st.session_state.analysis_cache.get(key)
122
 
123
+ ###########################################################################
124
  def display_morphosyntax_interface(lang_code, nlp_models, morpho_t):
 
 
 
 
125
  try:
126
  # CSS para layout estable
127
  st.markdown("""
 
146
  </style>
147
  """, unsafe_allow_html=True)
148
 
149
+ # Inicializar estados si no existen
150
  initialize_arc_analysis_state()
151
 
152
+ # -- Tabs: definimos 3 pestañas
 
 
 
 
 
 
 
153
  subtabs = st.tabs([
154
  "Análisis de Diagramas de Arco",
155
  "Análisis de Categorías",
156
  "Análisis Morfológico"
157
  ])
158
 
159
+ # =========== Pestaña 1: Diagrama de Arco ===============
160
  with subtabs[0]:
161
+ col1, col2, col3 = st.columns([2,1,2])
 
162
  with col1:
163
  if st.button("Nuevo Análisis", type="secondary", use_container_width=True):
164
  reset_morpho_state()
165
+
166
+ # Contenedor de todo el proceso
167
+ with st.container():
168
+ # Input texto original
 
 
 
 
169
  text_input = st.text_area(
170
+ "Ingrese su texto",
171
  value=st.session_state.arc_analysis_state.get('original_text', ''),
172
+ key=f"original_text_{st.session_state.arc_analysis_state['analysis_count']}",
173
  height=100
174
  )
175
 
176
+ analyze_button = st.button(
177
+ "Analizar Texto",
178
+ type="primary",
179
+ use_container_width=True
180
+ )
 
 
 
181
 
182
  # Procesar texto original
183
  if analyze_button and text_input.strip():
184
  try:
 
185
  doc = nlp_models[lang_code](text_input)
186
  analysis = perform_advanced_morphosyntactic_analysis(
187
  text_input,
188
  nlp_models[lang_code]
189
  )
190
 
191
+ # Guardar en Mongo
192
  base_id = store_student_morphosyntax_base(
193
  st.session_state.username,
194
  text_input,
 
196
  )
197
 
198
  if base_id:
199
+ # Actualizar estado
200
+ st.session_state.arc_analysis_state['base_id'] = base_id
201
+ st.session_state.arc_analysis_state['original_text'] = text_input
202
+ st.session_state.arc_analysis_state['analysis_count'] += 1
203
+
 
 
 
 
204
  display_arc_diagram(doc, analysis)
205
 
 
206
  st.markdown('<hr class="divider">', unsafe_allow_html=True)
207
 
208
+ # Caja de texto para la iteración
209
+ st.subheader("Iteración / Cambios:")
210
+ iteration_text = st.text_area(
211
+ "Ingrese cambios o versión modificada",
212
+ value=st.session_state.arc_analysis_state.get('iteration_text', ''),
213
+ key="iteration_text",
214
+ height=100
215
+ )
216
+
217
+ # Botón para analizar iteración
218
+ iteration_button = st.button(
219
+ "Analizar Cambios",
220
+ type="primary",
221
+ use_container_width=True
222
+ )
223
+
224
+ if iteration_button and iteration_text.strip():
 
 
 
 
 
 
 
225
  try:
226
  doc_iter = nlp_models[lang_code](iteration_text)
227
  analysis_iter = perform_advanced_morphosyntactic_analysis(
 
229
  nlp_models[lang_code]
230
  )
231
 
 
232
  iteration_id = store_student_morphosyntax_iteration(
233
  st.session_state.username,
234
  base_id,
235
+ text_input,
236
+ iteration_text,
237
  analysis_iter['arc_diagrams']
238
  )
239
 
240
  if iteration_id:
241
+ # Guardamos el texto de iteración en session_state
242
+ st.session_state.arc_analysis_state['iteration_text'] = iteration_text
 
 
 
 
243
  display_arc_diagram(doc_iter, analysis_iter)
244
 
245
  except Exception as e:
 
248
 
249
  except Exception as e:
250
  st.error("Error procesando análisis base")
251
+ logger.error(f"Error: {str(e)}")
252
 
253
+ # =========== Pestaña 2: Categorías (placeholder) ============
254
  with subtabs[1]:
255
  st.info("Análisis de Categorías en desarrollo...")
256
 
257
+ # =========== Pestaña 3: Análisis Morfológico (placeholder) ============
258
  with subtabs[2]:
259
  st.info("Análisis Morfológico en desarrollo...")
260
 
261
  except Exception as e:
262
+ st.error("Error en la interfaz")
263
  logger.error(f"Error general en la interfaz: {str(e)}")
264
 
265
+ ###########################################################################
266
  def display_morphosyntax_results(result, lang_code, morpho_t):
267
  """
268
  Muestra solo el diagrama de arco.
269
  Args:
270
  result: Diccionario con el documento procesado y su análisis
271
  lang_code: Código del idioma
272
+ morpho_t: Diccionario de traducciones
273
  """
274
  if result is None:
275
  return
276
+
277
  try:
278
  doc = result['doc']
279
  sentences = list(doc.sents)
280
  for i, sent in enumerate(sentences):
281
  try:
282
  st.subheader(f"{morpho_t.get('sentence', 'Sentence')} {i+1}")
283
+ rendered = displacy.render(sent, style="dep", options={
284
+ "distance": 100,
285
+ "arrow_spacing": 20,
286
+ "word_spacing": 30
287
+ })
288
+ rendered = rendered.replace('height="375"', 'height="200"')
289
+ rendered = re.sub(
 
 
 
 
290
  r'<svg[^>]*>',
291
  lambda m: m.group(0).replace('height="450"', 'height="300"'),
292
+ rendered
293
  )
294
+ rendered = re.sub(
295
  r'<g [^>]*transform="translate\((\d+),(\d+)\)"',
296
  lambda m: f'<g transform="translate({m.group(1)},50)"',
297
+ rendered
298
  )
299
+ rendered = f'<div class="arc-diagram-container">{rendered}</div>'
300
+ st.write(rendered, unsafe_allow_html=True)
301
+ except Exception as e:
302
+ logger.error(f"Error en diagrama {i}: {str(e)}")
303
  continue
304
  except Exception as e:
305
  logger.error(f"Error en display_morphosyntax_results: {str(e)}")
306
+