Skip to content

Commit 93201f4

Browse files
committed
fix: resolve jupyter-book build errors for GitHub Pages deploy
1 parent de66b71 commit 93201f4

11 files changed

Lines changed: 68 additions & 87 deletions

.github/workflows/deploy_pages.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
- name: 📦 Install dependencies
2020
run: |
2121
python -m pip install --upgrade pip
22-
pip install jupyter-book
22+
pip install "jupyter-book<2"
2323
2424
- name: 🏗️ Build the book
2525
run: |

_config.yml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,13 @@ title: Modelo VFT - Reportes de Ingeniería de Transportes en Urbanismo
22
author: Hernán Galileo Cabrera Garibaldi
33
#logo: notebooks/ASSETS/logo.png
44
execute:
5-
execute_notebooks: "off"
5+
execute_notebooks: "off"
6+
7+
exclude_patterns:
8+
- venv
9+
- src
10+
- tmp
11+
- ASSETS
12+
- .github
13+
- .claude
14+
- .vscode

_toc.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,6 @@ chapters:
1212

1313
- file: notebooks/02_Nivel_Cobertura
1414

15-
- file: notebooks/03_Fuerza_capilar
15+
- file: notebooks/03_Fuerza_capilar
16+
17+
- file: notebooks/NOTES/issues

notebooks/00_Construccion_grafo.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,4 +274,4 @@
274274
},
275275
"nbformat": 4,
276276
"nbformat_minor": 5
277-
}
277+
}

notebooks/01_Analisis_Impedancia_VFT.ipynb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1119,7 +1119,6 @@
11191119
"metadata": {},
11201120
"source": [
11211121
"<!--\n",
1122-
"---\n",
11231122
"## 5. Análisis Comparativo: Corrida Anterior vs. Corrida Actual\n",
11241123
"\n",
11251124
"Esta sección documenta las correcciones aplicadas al modelo y contrasta los valores de $C_f$ calculados con los estimados en la tesis.\n",
@@ -1175,4 +1174,4 @@
11751174
},
11761175
"nbformat": 4,
11771176
"nbformat_minor": 5
1178-
}
1177+
}

notebooks/02_Nivel_Cobertura.ipynb

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@
410410
{
411411
"data": {
412412
"text/markdown": [
413-
"---"
413+
"<hr/>"
414414
],
415415
"text/plain": [
416416
"<IPython.core.display.Markdown object>"
@@ -542,7 +542,7 @@
542542
{
543543
"data": {
544544
"text/markdown": [
545-
"---"
545+
"<hr/>"
546546
],
547547
"text/plain": [
548548
"<IPython.core.display.Markdown object>"
@@ -667,7 +667,7 @@
667667
{
668668
"data": {
669669
"text/markdown": [
670-
"---"
670+
"<hr/>"
671671
],
672672
"text/plain": [
673673
"<IPython.core.display.Markdown object>"
@@ -792,7 +792,7 @@
792792
{
793793
"data": {
794794
"text/markdown": [
795-
"---"
795+
"<hr/>"
796796
],
797797
"text/plain": [
798798
"<IPython.core.display.Markdown object>"
@@ -924,7 +924,7 @@
924924
{
925925
"data": {
926926
"text/markdown": [
927-
"---"
927+
"<hr/>"
928928
],
929929
"text/plain": [
930930
"<IPython.core.display.Markdown object>"
@@ -1056,7 +1056,7 @@
10561056
{
10571057
"data": {
10581058
"text/markdown": [
1059-
"---"
1059+
"<hr/>"
10601060
],
10611061
"text/plain": [
10621062
"<IPython.core.display.Markdown object>"
@@ -1188,7 +1188,7 @@
11881188
{
11891189
"data": {
11901190
"text/markdown": [
1191-
"---"
1191+
"<hr/>"
11921192
],
11931193
"text/plain": [
11941194
"<IPython.core.display.Markdown object>"
@@ -1320,7 +1320,7 @@
13201320
{
13211321
"data": {
13221322
"text/markdown": [
1323-
"---"
1323+
"<hr/>"
13241324
],
13251325
"text/plain": [
13261326
"<IPython.core.display.Markdown object>"
@@ -1452,7 +1452,7 @@
14521452
{
14531453
"data": {
14541454
"text/markdown": [
1455-
"---"
1455+
"<hr/>"
14561456
],
14571457
"text/plain": [
14581458
"<IPython.core.display.Markdown object>"
@@ -1584,7 +1584,7 @@
15841584
{
15851585
"data": {
15861586
"text/markdown": [
1587-
"---"
1587+
"<hr/>"
15881588
],
15891589
"text/plain": [
15901590
"<IPython.core.display.Markdown object>"
@@ -1716,7 +1716,7 @@
17161716
{
17171717
"data": {
17181718
"text/markdown": [
1719-
"---"
1719+
"<hr/>"
17201720
],
17211721
"text/plain": [
17221722
"<IPython.core.display.Markdown object>"
@@ -1848,7 +1848,7 @@
18481848
{
18491849
"data": {
18501850
"text/markdown": [
1851-
"---"
1851+
"<hr/>"
18521852
],
18531853
"text/plain": [
18541854
"<IPython.core.display.Markdown object>"
@@ -2046,4 +2046,4 @@
20462046
},
20472047
"nbformat": 4,
20482048
"nbformat_minor": 5
2049-
}
2049+
}

notebooks/03_Fuerza_capilar.ipynb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@
160160
"id": "8a78df4c",
161161
"metadata": {},
162162
"source": [
163-
"---\n",
163+
"<hr/>\n",
164164
"## 5. Análisis Geográfico: Macro-Hubs Intermodales\n",
165165
"Este enfoque revela la infraestructura física de transbordo. Al agrupar estaciones cercanas, emergen los grandes polígonos de movilidad de la ciudad."
166166
]
@@ -10199,7 +10199,7 @@
1019910199
"id": "0ecd829d",
1020010200
"metadata": {},
1020110201
"source": [
10202-
"---\n",
10202+
"<hr/>\n",
1020310203
"## 6. Análisis Matemático: Centralidad Estricta\n",
1020410204
"Evalúa la convergencia puntual sin agrupaciones, detectando puntos específicos (coordenadas únicas) que soportan una gran carga de vectores vehiculares."
1020510205
]
@@ -10622,7 +10622,7 @@
1062210622
"id": "93ef8b59",
1062310623
"metadata": {},
1062410624
"source": [
10625-
"---\n",
10625+
"<hr/>\n",
1062610626
"### 6.1. Distribución de la Capilaridad Matemática (Ley de Potencias)\n",
1062710627
"La topología de la red sigue una distribución de **Scale-Free Network** (Ley de Potencias). \n",
1062810628
"¿Por qué ocurre esto? En los sistemas de transporte reales, la inmensa mayoría de las paradas actúan como nodos de paso simples (1 conexión de entrada y 1 de salida = FC de 2). Por el contrario, un grupo extremadamente reducido de nodos actúa como absorbedores masivos de rutas (decenas de conexiones). Esta desigualdad genera la curva logarítmica descendente que vemos a continuación."
@@ -10761,7 +10761,7 @@
1076110761
"id": "1cc75250",
1076210762
"metadata": {},
1076310763
"source": [
10764-
"---\n",
10764+
"<hr/>\n",
1076510765
"## 7. Anexo: Diagnóstico Especulativo para Ruta Anillar (Periférico)\n",
1076610766
"Este apartado aísla los nodos y Macro-Hubs que cruzan o se nombran \"Periférico\". Se divide en la perspectiva Matemática y Geográfica para identificar anclajes potenciales."
1076710767
]
@@ -17892,7 +17892,7 @@
1789217892
"id": "a105e9e7",
1789317893
"metadata": {},
1789417894
"source": [
17895-
"---\n",
17895+
"<hr/>\n",
1789617896
"**Nota Aclaratoria:** *Los mapas mostrados en la Sección 7 representan únicamente una evaluación de la infraestructura preexistente. Aún no se traza ni se mapea el recorrido geométrico propuesto para el \"Corredor Anillar\", por lo que esta sección se mantiene en un plano puramente especulativo para identificar los puntos naturales de anclaje de la futura línea.*"
1789717897
]
1789817898
},
@@ -17924,4 +17924,4 @@
1792417924
},
1792517925
"nbformat": 4,
1792617926
"nbformat_minor": 5
17927-
}
17927+
}

notebooks/NOTES/graph_builder.md

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
**¿Qué hace este archivo en resumen?**
44
Es el "arquitecto" de nuestra red. Toma todas las estaciones y líneas de transporte sueltas y las teje para formar un grafo (una red conectada). Su trabajo más importante es simular la realidad: conectar estaciones cercanas para que el usuario pueda transbordar caminando, cobrándole el tiempo de caminata más el tiempo de espera en el andén.
55

6-
---
7-
6+
<hr/>
87
## 1. Los Diccionarios Base (Los Acuerdos de la Realidad)
98

109
Antes de conectar cosas, la clase `VFTGraphBuilder` define las reglas del juego usando diccionarios:
@@ -29,17 +28,15 @@ FALLBACK_FRECUENCIA = {
2928
}
3029
```
3130

32-
---
33-
31+
<hr/>
3432
## 2. El Director de Orquesta: `build_graph()`
3533

3634
Es la función principal. Lo que hace es:
3735

3836
1. Construye las vías normales (trenes y camiones avanzando de estación a estación).
3937
2. Si le decimos que opere en modo `"REALISTIC_INTEGRATION"`, manda llamar a la función de "snapping" para crear los caminos peatonales invisibles entre estaciones cercanas.
4038

41-
---
42-
39+
<hr/>
4340
## 3. La Magia de los Transbordos: `_apply_pedestrian_snapping()`
4441

4542
Aquí es donde ocurre la integración intermodal. El algoritmo agarra un compás, se para en una estación y busca si hay otras estaciones dentro del radio de tolerancia (ej. 85 metros). Si encuentra una, crea un puente peatonal de ida y vuelta.
@@ -62,8 +59,7 @@ wait_v = self.FALLBACK_FRECUENCIA.get(sistema_v, 10.0) / 2.0
6259
peso_total = tiempo_caminata_min + wait_v
6360
```
6461

65-
---
66-
62+
<hr/>
6763
## 🚨 Justificación Técnica de la Velocidad Peatonal
6864

6965
Para calcular el `tiempo_caminata_min`, en el código hacemos una conversión equivalente a caminar a **5 km/h (1.38 m/s)**.
@@ -74,8 +70,7 @@ Para calcular el `tiempo_caminata_min`, en el código hacemos una conversión eq
7470
7571
Como nuestro modelo asume un trayecto de transferencia (población económicamente activa en movimiento continuo dentro de un nodo de transbordo sin esperar semáforos), adoptamos el límite superior de **1.38 m/s (5 km/h)**, logrando un balance entre la norma urbana y los cálculos de isócronas globales.
7672

77-
---
78-
73+
<hr/>
7974
## ⚠️ Limitante de Datos: Cobertura Incompleta de Cablebús (CBB)
8075

8176
El backend Go (`apimetro_db`) reporta únicamente **19 estaciones de Cablebús** en la tabla `lineas` (verificado 2026-04-18). El sistema real opera con más estaciones distribuidas en las Líneas 1 y 2.
@@ -84,8 +79,7 @@ El backend Go (`apimetro_db`) reporta únicamente **19 estaciones de Cablebús**
8479
- **Impacto en Fuerza Capilar:** los nodos masivos de CBB reciben menos conexiones de superficie de las reales.
8580
- **Acción requerida:** verificar tabla `lineas` en `apimetro_db` filtrando `sistema = 'CBB'` y completar el registro de estaciones faltantes. Hasta entonces, los indicadores de CBB deben interpretarse como estimaciones conservadoras.
8681

87-
---
88-
82+
<hr/>
8983
## 📐 Fundamento del Coeficiente de Fricción Vial (CF) — alpha por derecho de vía
9084

9185
El `FrictionCalculator` en `src/core/models/impedance.py` usa la siguiente tabla de `alpha` para calcular `CF = 1 + (alpha × BETA_SATURACION_CDMX)`:
@@ -103,8 +97,7 @@ El `FrictionCalculator` en `src/core/models/impedance.py` usa la siguiente tabla
10397

10498
**Nota metodológica:** Los `FALLBACK_VELOCIDAD` en `VFTImpedanceModel` representan **velocidad de flujo libre** (sin congestión). El CF aplica la penalización. Esta separación evita el double-counting que ocurriría si el fallback ya incorporara congestión y el CF la volviera a aplicar.
10599

106-
---
107-
100+
<hr/>
108101
## 🔬 Observación de Semántica de Datos: Banqueta vs. Carril (Apimetro ↔ VFTModel)
109102

110103
### El problema

notebooks/NOTES/impedance.md

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@
33
**¿Qué hace este archivo en resumen?**
44
Es el "tasador de tiempo" de la red. Una vez que `graph_builder.py` construyó el grafo con sus nodos y aristas, este módulo recorre cada segmento y le inyecta un **peso temporal en minutos** basado en tres factores reales: la distancia física del tramo, la velocidad comercial del sistema, y el nivel de interferencia del tráfico urbano sobre esa vía. Es la implementación directa de la **Ecuación VFT**.
55

6-
---
7-
6+
<hr/>
87
## 1. `FrictionCalculator` — El Coeficiente de Fricción Vial (Cf)
98

109
Este módulo auxiliar traduce el tipo de derecho de vía de una línea en un penalizador matemático. La idea central: no es lo mismo correr por un túnel del Metro (sin semáforos, sin tráfico) que circular en un camión por Insurgentes entre autos particulares.
@@ -42,8 +41,7 @@ cf = 1.0 + (alpha * BETA_SATURACION_CDMX)
4241

4342
El valor por defecto si no se conoce el derecho de vía es `"mixto"` (el peor caso).
4443

45-
---
46-
44+
<hr/>
4745
## 2. `VFTImpedanceModel` — El Motor de Impedancia
4846

4947
### 2.1 Tablas de Fallback
@@ -80,8 +78,7 @@ FALLBACK_FRECUENCIA = {
8078

8179
> **Nota de inconsistencia:** `CBB` tiene frecuencia `10.0` min aquí pero `1.0` min en `graph_builder.py`. Requiere definición canónica.
8280
83-
---
84-
81+
<hr/>
8582
### 2.2 `haversine()` — La Distancia Real del Segmento
8683

8784
```python
@@ -101,8 +98,7 @@ def haversine(lon1, lat1, lon2, lat2) -> float:
10198

10299
**Firma importante:** recibe `(lon, lat, lon, lat)` — primero longitud, luego latitud. Los nodos del grafo están almacenados como `(lon, lat)`, así que la llamada siempre es `haversine(u[0], u[1], v[0], v[1])`.
103100

104-
---
105-
101+
<hr/>
106102
### 2.3 `apply_impedance()` — La Inyección sobre el Grafo
107103

108104
Este método itera sobre todas las aristas del grafo `DiGraph` y aplica la Ecuación VFT en 6 pasos:
@@ -145,8 +141,7 @@ for u, v, data in self.G.edges(data=True):
145141

146142
> **Decisión de diseño clave:** el `weight` solo incluye `travel_time_min`, **no** `boarding_cost_min`. El boarding cost se registra como atributo informativo pero no penaliza el camino en los segmentos normales. La penalización por espera ocurre únicamente en las aristas de transbordo peatonal, donde sí se suma al weight (`tiempo_caminata + wait`).
147143
148-
---
149-
144+
<hr/>
150145
## 3. El Flujo Completo en Contexto
151146

152147
```
@@ -160,8 +155,7 @@ GeoJSON → VFTGraphBuilder → [Grafo base + transbordos peatonales]
160155
Grafo listo para Dijkstra / análisis topológico
161156
```
162157

163-
---
164-
158+
<hr/>
165159
## 4. Issues Abiertos sobre este Módulo
166160

167161
1. **Velocidad INTERURBANO (160 km/h):** El fallback de 160 km/h corresponde a velocidad de diseño del tren, no comercial. La velocidad operativa real es ~70 km/h. Requiere corrección.

notebooks/NOTES/issues.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55
### Correcciones Aplicadas
66

77
| # | Archivo | Cambio | Estado |
8-
|---|---|---|---|
8+
|<hr/>|<hr/>|<hr/>|<hr/>|
99
| 1 | `src/core/models/impedance.py` | `FALLBACK_VELOCIDAD["INTERURBANO"]`: 160 km/h → **70 km/h** (velocidad comercial real) | ✅ RESUELTO |
1010
| 2 | `src/core/services/graph_builder.py` | `FALLBACK_FRECUENCIA["CBB"]`: 1.0 min → **10.0 min** (alineado con `impedance.py`) | ✅ RESUELTO |
1111
| 3 | `notebooks/01_Analisis_Impedancia_VFT.ipynb` | Separación de `df_edges` (servicio real) vs `df_transfers` (transbordo peatonal). Antes se mezclaban, contaminando el análisis. | ✅ RESUELTO |
1212
| 4 | `apimetro_db` (docker-dev, puerto 5433) | `historico_operacion.velocidad_promedio_kmh` para ramal Interurbano corregida a 70.0 km/h vía UPDATE directo. | ✅ RESUELTO |
1313

14-
---
14+
<hr/>
1515

1616
### Issues Abiertos (pendientes)
1717

@@ -40,7 +40,7 @@
4040
- **Descripción:** Los valores `alpha = {0.0, 0.2, 0.5, 1.0}` para los cuatro tipos de derecho de vía requieren cita exacta del Manual de Calles SEDATU 2019 (tabla y párrafo).
4141
- **Archivo:** `src/core/models/impedance.py``FrictionCalculator.alpha_map`; `notebooks/NOTES/impedance.md` — Sección 1
4242

43-
---
43+
<hr/>
4444

4545
### Contexto de corrida (2026-04-16)
4646

0 commit comments

Comments
 (0)