Pronóstico y backtest de crecimiento de maíz con CFS

Este es un pronóstico térmico experimental de maíz para 2024, evaluado fuera de muestra; no es asesoramiento agronómico. El panel pregunta cuándo las etapas estatales superarían el 50% si el desarrollo siguiera la temperatura acumulada en una celda de CFS.

Cómo se construye el pronóstico

El panel usa CFS FLXF de NOAA, cuyas salidas cada seis horas se extienden hasta aproximadamente 215 días, con un modelo modificado de Growing Degree Days (GDD) calibrado y evaluado con los informes de progreso de cultivos de USDA. Esto permite crear un pronóstico térmico para toda la temporada con supuestos y umbrales inspeccionables.

El caso está congelado al 1 de julio de 2024 a las 00 UTC. Une historia CFS con plazo exacto de seis horas antes de esa fecha y un único ciclo archivado después. La historia sigue siendo guía de modelo, no observaciones, y no se agregan ciclos posteriores.

Como CFS es grueso, cada serie usa una coordenada nativa de la grilla gaussiana, no una ciudad ni un promedio estatal:

EstadoLatitudLongitud
Iowa42.047066-93.750371
Nebraska41.102190-99.375363
Kansas38.267561-100.312862
Indiana40.157314-86.250381
Missouri39.212437-92.812872
Ohio40.157314-82.500386
North Dakota46.771444-98.437864

Cálculo térmico de seis horas

En cada intervalo se convierten TMAX y TMIN a Fahrenheit, se limitan al rango 50–86 °F, se promedian, se resta la base de 50 °F y se multiplica por un cuarto de día:

Tmax_F = (TMAX_K - 273.15) × 9 / 5 + 32
Tmin_F = (TMIN_K - 273.15) × 9 / 5 + 32

GDD50_6h = (
  (clamp(Tmax_F, 50, 86) + clamp(Tmin_F, 50, 86)) / 2 - 50
) × 6 / 24

La base de 50 °F y el techo de 86 °F siguen el método modificado de Iowa State University Extension. Aplicarlo a cada intervalo no equivale exactamente a calcular primero máximos y mínimos diarios; por eso los umbrales se calibraron en esta misma métrica de seis horas.

Cómo se generaron las constantes

Los objetivos proceden de USDA NASS Crop Progress and Condition. Interpolamos linealmente el momento en que el porcentaje semanal estatal cruza el 50%. El 50% sembrado inicia la acumulación; emergencia, floración femenina, grano pastoso, dentado y madurez son los objetivos.

Para cada estado, año y etapa, el umbral implícito es el GDD acumulado entre ambas fechas. Para evitar usar 2024 en su propia calibración, las constantes del panel son la mediana de 2020–2023. Es una calibración histórica pequeña, no entrenamiento de aprendizaje automático:

EstadoEmergenciaFloración femeninaGrano pastosoDentadoMadurez
Iowa113.4751332.4091739.1392163.2472563.627
Nebraska142.0861388.0371898.4942357.7202892.070
Kansas166.0021557.5222111.4452664.3863290.921
Indiana115.4661275.0901766.8122228.1592632.039
Missouri72.7291389.5161874.2762365.3142910.735
Ohio127.7561277.1391677.8362173.6492538.914
North Dakota177.1231116.5681623.3711963.7592248.754

Las diferencias entre estados son intencionales: una única madurez nacional funcionó mal. Las constantes absorben mezcla de cultivos, madurez relativa, patrones de siembra y el desajuste entre una celda y un estado.

¿Es plausible el pronóstico archivado?

Repetimos el ajuste con validación leave-one-year-out para 2020–2024. Para la misma división historia-pronóstico del 1 de julio, los resultados fuera de muestra fueron:

EtapaPrevistos / elegiblesCoberturaSesgoError absoluto medioMediana del error absoluto
Floración femenina35 / 35100%-0.9 días2.5 días1.7 días
Grano pastoso35 / 35100%-0.9 días3.3 días1.9 días
Dentado34 / 3597%+0.8 días4.7 días3.6 días
Madurez32 / 3591%+2.9 días6.5 días4.2 días

La cobertura es la fracción de temporadas elegibles que alcanzó la etapa antes de terminar el pronóstico. El sesgo es fecha prevista menos fecha USDA. Los resultados hacen plausible una estimación de madurez de aproximadamente una semana en julio como demo, no para un lote particular ni como garantía futura.

Limitaciones importantes

Cómo reproducir el cálculo meteorológico

El panel agrupa siete coordenadas; estas dos solicitudes mínimas para Iowa muestran el cálculo completo. Grafana concatena las contribuciones, descuenta el GDD anterior a la siembra y calcula la suma acumulada.

Solicitud de historia con plazo exacto de seis horas

curl -X POST 'https://gribstream.com/api/v2/cfsflxf/timeseries' \
  -H "Content-Type: application/json" \
  -H "Accept: text/csv" \
  -H "Authorization: Bearer [API_TOKEN]" \
  -d '{
    "fromTime": "2024-04-15T06:00:00Z",
    "untilTime": "2024-07-01T06:00:00Z",
    "asOf": "2024-11-02T00:00:00Z",
    "minLeadTime": "6h",
    "maxLeadTime": "6h",
    "coordinates": [
      {"name": "Iowa", "lat": 42.047066, "lon": -93.750371}
    ],
    "variables": [
      {"name": "TMAX", "level": "2 m above ground", "info": "", "alias": "temperature_max_k", "hidden": true},
      {"name": "TMIN", "level": "2 m above ground", "info": "", "alias": "temperature_min_k", "hidden": true}
    ],
    "expressions": [
      {"expression": "(temperature_max_k - 273.15) * 9 / 5 + 32", "alias": "temperature_max_f"},
      {"expression": "(temperature_min_k - 273.15) * 9 / 5 + 32", "alias": "temperature_min_f"},
      {"expression": "((func.Min(86.0, func.Max(50.0, temperature_max_f)) + func.Min(86.0, func.Max(50.0, temperature_min_f))) / 2 - 50.0) * 0.25", "alias": "gdd50_f_degree_days_6h"}
    ]
  }'

Solicitud del pronóstico archivado del 1 de julio

curl -X POST 'https://gribstream.com/api/v2/cfsflxf/runs' \
  -H "Content-Type: application/json" \
  -H "Accept: text/csv" \
  -H "Authorization: Bearer [API_TOKEN]" \
  -d '{
    "forecastedFrom": "2024-07-01T00:00:00Z",
    "forecastedUntil": "2024-07-01T00:00:00Z",
    "minLeadTime": "6h",
    "maxLeadTime": "2952h",
    "coordinates": [
      {"name": "Iowa", "lat": 42.047066, "lon": -93.750371}
    ],
    "variables": [
      {"name": "TMAX", "level": "2 m above ground", "info": "", "alias": "temperature_max_k", "hidden": true},
      {"name": "TMIN", "level": "2 m above ground", "info": "", "alias": "temperature_min_k", "hidden": true}
    ],
    "expressions": [
      {"expression": "(temperature_max_k - 273.15) * 9 / 5 + 32", "alias": "temperature_max_f"},
      {"expression": "(temperature_min_k - 273.15) * 9 / 5 + 32", "alias": "temperature_min_f"},
      {"expression": "((func.Min(86.0, func.Max(50.0, temperature_max_f)) + func.Min(86.0, func.Max(50.0, temperature_min_f))) / 2 - 50.0) * 0.25", "alias": "gdd50_f_degree_days_6h"}
    ]
  }'

Filas de ejemplo en la unión entre historia y pronóstico:

forecasted_at,forecasted_time,lat,lon,name,member,gdd50_f_degree_days_6h,temperature_max_f,temperature_min_f
2024-06-30T18:00:00Z,2024-07-01T00:00:00Z,42.0471,-93.7504,Iowa,0,4.7475,70.2500,67.7300
2024-07-01T00:00:00Z,2024-07-01T06:00:00Z,42.0471,-93.7504,Iowa,0,3.3300,69.5300,57.1100

Fuentes primarias: documentación NOAA CFSv2 · modelo e inventario CFS FLXF · metodología USDA NASS · archivo oficial Crop Progress · método GDD de Iowa State.