Cómo Funciona TEMPO y Resolución Temporal
TEMPO utiliza espectroscopía UV-visible para medir gases desde el espacio. En esta lección entenderemos el principio básico y cómo aprovechar la ventaja horaria.
Principio: Espectroscopía de Absorción
Los gases absorben luz en longitudes de onda específicas, como "huellas dactilares" únicas.
Concepto básico:
- Sol emite luz de todos los colores
- Gases en atmósfera absorben colores específicos
- TEMPO mide qué colores faltan
- Calcula cuánto gas hay
Huellas Espectrales
Cada gas absorbe luz en rangos diferentes:
| Gas | Longitud de onda | Color | Por qué importa |
|---|---|---|---|
| NO₂ | 400-450 nm | Azul-violeta | Absorción fuerte, fácil detectar |
| O₃ | 255 nm (UV) + 600 nm (naranja) | UV + Naranja | Dos bandas permiten separar troposfera/estratosfera |
| HCHO | 340 nm | UV-A | Más débil, requiere procesamiento |
Esto explica por qué TEMPO opera en rango UV-Visible (290-740 nm): los gases de interés absorben luz ahí.
Ley de Beer-Lambert (Simplificada)
La base matemática:
En palabras simples:
- Más gas = menos luz transmitida
- TEMPO mide la luz que falta
- Calcula concentración del gas
TEMPO mide la columna vertical total de gas (superficie → espacio), no concentración a nivel del suelo.
Unidades: moléculas/cm² (columna completa)
De Luz a Datos: El Pipeline
NASA hace el procesamiento complejo por ti. Entender el pipeline te ayuda a usar los datos correctamente.
Niveles de Productos
Para desarrolladores:
| Nivel | Qué contiene | ¿Usar en tu app? |
|---|---|---|
| L0/L1A | Datos crudos | ❌ No |
| L1B | Radiancias calibradas | ❌ No (muy técnico) |
| L2 | Concentraciones de gases | ✅ SÍ - USA ESTE |
| L3 | Grillas diarias/mensuales | ✅ Sí (para análisis histórico) |
NASA proporciona productos L2 listos para usar. Como desarrollador, trabajas directamente con:
- Columnas de NO₂ (molec/cm²)
- Columnas de O₃ (DU)
- Columnas de HCHO (molec/cm²)
No necesitas implementar algoritmos de espectroscopía.
Control de Calidad
Los productos L2 incluyen banderas de calidad (quality flags).
Quality Flags
1interface TempoPixel {
2 no2_column: number;
3 cloud_fraction: number;
4 quality_flag: number; // 0 = alta, 1 = media, 2 = baja
5}
6
7function shouldUseData(pixel: TempoPixel): boolean {
8 // Filtrar baja calidad
9 if (pixel.quality_flag > 1) {
10 return false; // Descarta
11 }
12
13 // Filtrar alta cobertura de nubes
14 if (pixel.cloud_fraction > 0.7) {
15 return false; // Las nubes bloquean la vista
16 }
17
18 return true; // OK para usar
19}
20En tu app: Siempre filtra datos con quality_flag > 1 para evitar valores erróneos.
Precisión de TEMPO
Incertidumbres Esperadas
| Producto | Precisión (píxel individual) | Precisión (promedio espacial) |
|---|---|---|
| NO₂ troposférico | ~0.5 × 10¹⁵ molec/cm² | ~0.3 × 10¹⁵ molec/cm² |
| O₃ total | ~3% | ~1-2% |
| O₃ troposférico | ~20% | ~10% |
| HCHO | ~1 × 10¹⁶ molec/cm² | ~0.5 × 10¹⁶ molec/cm² |
Tip: Promediar múltiples píxeles mejora la precisión.
Resolución Temporal: La Ventaja de TEMPO
TEMPO observa cada hora desde aproximadamente 8 AM hasta 10 PM hora local.
Cobertura Temporal por Ubicación
| Ubicación | Primera Obs | Última Obs | Obs/Día |
|---|---|---|---|
| New York (EST) | 08:00 | 22:00 | 14 |
| Los Angeles (PST) | 07:00 | 21:00 | 14 |
| Ciudad de México | 08:30 | 22:30 | 14 |
Capturando el Ciclo Diurno
La variación hora por hora revela patrones importantes.
Ciclo Típico de NO₂ en Ciudad
1def simulate_no2_diurnal_cycle(hour_local):
2 """
3 Ciclo diurno típico de NO₂ en ciudad
4 Retorna: Columna NO₂ en 10¹⁵ molec/cm²
5 """
6 # Background base
7 background = 2.0
8
9 # Pico matutino (7-9 AM)
10 if 7 <= hour_local <= 9:
11 morning_peak = 6.0
12 else:
13 morning_peak = 0
14
15 # Pico vespertino (5-7 PM)
16 if 17 <= hour_local <= 19:
17 evening_peak = 7.0
18 else:
19 evening_peak = 0
20
21 # Mínimo diurno (mezcla vertical)
22 if 12 <= hour_local <= 15:
23 mixing_reduction = -1.5
24 else:
25 mixing_reduction = 0
26
27 return max(0.5, background + morning_peak + evening_peak + mixing_reduction)
28
29# Simular día completo
30for hour in range(8, 23):
31 no2 = simulate_no2_diurnal_cycle(hour)
32 print(f"{hour:02d}:00 - NO₂: {no2:.2f} × 10¹⁵ molec/cm²")
33Output típico:
- 08:00 - NO₂: 8.0 (pico AM) 🔴
- 12:00 - NO₂: 0.5 (mínimo) 🟢
- 18:00 - NO₂: 9.0 (pico PM) 🔴
- 22:00 - NO₂: 2.0 (descenso) 🟡
Ciclo Típico de O₃
El ozono muestra un patrón diferente:
- Mañana (8-12h): O₃ bajo, formación comienza
- Tarde (12-18h): O₃ alcanza pico máximo
- Noche: O₃ desciende (sin luz solar)
Comprender ciclos diurnos permite:
- ⏰ Timing de alertas: "O₃ alcanzará nivel insalubre en 2 horas"
- 🚗 Política de transporte: Reducir tráfico en horas críticas
- 📊 Validación: Verificar si modelos capturan variación horaria
Detección de Eventos
La resolución horaria permite detectar y rastrear eventos de contaminación.
Tipos de Eventos Detectables
1. Incendios Forestales
- Plumas de humo detectables por aumento de HCHO
- Seguimiento hora por hora de movimiento
- Predicción de llegada a ciudades
2. Episodios de Ozono
- Formación matutina visible
- Pico vespertino cuantificado
- Predicción 2-4h adelante
3. Inversiones Térmicas
- Acumulación nocturna
- Ruptura matinal observable
- Patrón vertical capturado
Ejemplo: Tracking Simple de Pluma
1interface PlumeObservation {
2 timestamp: Date;
3 centroid_lat: number;
4 centroid_lon: number;
5 hcho_column: number;
6}
7
8function trackPlumeMovement(observations: PlumeObservation[]) {
9 if (observations.length < 2) return null;
10
11 const first = observations[0];
12 const last = observations[observations.length - 1];
13
14 // Distancia simple (aproximación)
15 const lat_diff = last.centroid_lat - first.centroid_lat;
16 const lon_diff = last.centroid_lon - first.centroid_lon;
17 const distance_km = Math.sqrt(lat_diff**2 + lon_diff**2) * 111;
18
19 // Tiempo transcurrido
20 const hours = (last.timestamp.getTime() - first.timestamp.getTime()) / (1000 * 60 * 60);
21
22 return {
23 velocity_kmh: distance_km / hours,
24 direction: lon_diff > 0 ? 'Este' : 'Oeste',
25 distance_traveled: distance_km,
26 hours_elapsed: hours
27 };
28}
29
30// Ejemplo
31const observations = [
32 { timestamp: new Date('2025-10-02T14:00'), centroid_lat: 19.5, centroid_lon: -99.1, hcho_column: 3e16 },
33 { timestamp: new Date('2025-10-02T16:00'), centroid_lat: 19.6, centroid_lon: -98.9, hcho_column: 2.5e16 }
34];
35
36const movement = trackPlumeMovement(observations);
37console.log(`Pluma se mueve a ${movement.velocity_kmh} km/h hacia el ${movement.direction}`);
38Tracking de plumas es útil para:
- 🔥 Incendios forestales (alertar ciudades en trayectoria)
- 🏭 Releases industriales accidentales
- 🌋 Erupciones volcánicas
Para monitoreo urbano simple, no necesitas este nivel de complejidad.
Conexión con el Challenge de NASA
La resolución horaria es tu ventaja competitiva:
Casos de Uso Prácticos
1. Dashboard en Tiempo Real
1// Actualizar cada hora automáticamente
2setInterval(async () => {
3 const latestData = await fetchTEMPOLatest();
4 updateDashboard(latestData);
5}, 3600000); // 1 hora
62. Alertas Inteligentes
1function predictNextHour(last6hours: HourlyData[]): string {
2 const recent_no2 = last6hours.slice(-3).map(h => h.no2);
3 const trend = (recent_no2[2] - recent_no2[0]) / 2;
4
5 if (trend > 2e15) {
6 return "⚠️ NO₂ subiendo rápido - tráfico aumentando";
7 } else if (trend < -2e15) {
8 return "✅ NO₂ bajando - calidad mejorando";
9 }
10 return "➡️ NO₂ estable";
11}
123. Comparaciones Temporales
- Hoy vs ayer a la misma hora
- Día de semana vs fin de semana
- Antes/después de políticas ("Hoy No Circula")
4. Visualizaciones Efectivas
- Gráficos de línea mostrando últimas 12 horas
- Animaciones de evolución horaria
- Mapas de calor temporales
Ejemplo Simple para Implementar
1interface HourlyTrend {
2 hour: number;
3 no2: number;
4 o3: number;
5 trend: 'rising' | 'falling' | 'stable';
6}
7
8function analyzeTrend(data: HourlyTrend[]): string {
9 const last3hours = data.slice(-3);
10
11 const no2_trend = last3hours[2].no2 - last3hours[0].no2;
12
13 if (no2_trend > 3e15) {
14 return "🔴 NO₂ aumentando rápidamente - posible evento de tráfico o industrial";
15 } else if (no2_trend < -3e15) {
16 return "🟢 NO₂ disminuyendo - condiciones mejorando";
17 }
18
19 return "🟡 Condiciones estables";
20}
21No necesitas ML complejo - tendencias simples son muy efectivas.
Próximos Pasos
En la siguiente lección discutiremos las limitaciones de TEMPO: qué no puede medir, cuándo no hay datos, y cómo diseñar una arquitectura robusta que combine múltiples fuentes.