Previsão e backtest de crescimento do milho com CFS

Esta é uma previsão térmica experimental do milho para 2024, avaliada fora da amostra, e não orientação agronômica. O painel pergunta quando os estágios estaduais cruzariam 50% se o desenvolvimento acompanhasse o calor acumulado em uma célula do CFS.

Como a previsão é construída

O painel usa o CFS FLXF da NOAA, cujas saídas a cada seis horas se estendem por cerca de 215 dias, com um modelo modificado de Growing Degree Days (GDD) calibrado e avaliado com os relatórios de progresso das lavouras do USDA. Isso produz uma previsão térmica para toda a safra, mantendo premissas e limites verificáveis.

O caso está congelado em 1º de julho de 2024 às 00 UTC. Ele une o histórico CFS de prazo exato de seis horas antes desse instante a um único ciclo arquivado depois. O histórico ainda é orientação de modelo, não observação, e ciclos posteriores não são combinados.

Como o CFS tem resolução grosseira, cada série usa uma coordenada nativa da grade gaussiana, e não uma cidade ou média estadual:

EstadoLatitudeLongitude
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

Em cada intervalo, TMAX e TMIN são convertidas para Fahrenheit, limitadas a 50–86 °F, promediadas, subtraídas da base de 50 °F e multiplicadas por um quarto de dia:

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

A base de 50 °F e o teto de 86 °F seguem o método modificado da Iowa State University Extension. Aplicá-lo a cada intervalo não equivale exatamente a obter primeiro extremos diários; portanto, os limites foram calibrados nesta mesma métrica de seis horas.

Como as constantes foram geradas

Os alvos vêm do USDA NASS Crop Progress and Condition. Interpolamos linearmente o instante em que o percentual semanal estadual cruza 50%. O plantio a 50% inicia a acumulação; emergência, florescimento, grão pastoso, dentado e maturidade são os alvos.

Para cada estado, ano e estágio, o limite implícito é o GDD acumulado entre as duas datas. Para que 2024 não participe da própria calibração, as constantes do painel são as medianas de 2020–2023. É uma pequena calibração histórica, não treinamento de aprendizado de máquina:

EstadoEmergênciaFlorescimentoGrão pastosoDentadoMaturidade
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

As diferenças estaduais são intencionais: um único limite nacional funcionou mal. As constantes absorvem cultivares, maturidade relativa, calendários de plantio e a diferença entre uma célula e um estado.

A previsão arquivada parece plausível?

Repetimos o ajuste com validação leave-one-year-out em 2020–2024. Para a mesma divisão histórico-previsão de 1º de julho, os resultados fora da amostra foram:

EstágioPrevistos / elegíveisCoberturaViésErro absoluto médioMediana do erro absoluto
Florescimento35 / 35100%-0.9 dias2.5 dias1.7 dias
Grão pastoso35 / 35100%-0.9 dias3.3 dias1.9 dias
Dentado34 / 3597%+0.8 dias4.7 dias3.6 dias
Maturidade32 / 3591%+2.9 dias6.5 dias4.2 dias

Cobertura é a parcela de safras elegíveis que atingiu o estágio antes do fim da previsão. Viés é data prevista menos data USDA. Os números tornam plausível, como demo, uma estimativa de maturidade de aproximadamente uma semana em julho; não garantem um talhão nem a próxima previsão.

Limitações importantes

Como reproduzir o cálculo meteorológico

O painel agrupa sete coordenadas; estas duas requisições mínimas para Iowa mostram o cálculo completo. O Grafana concatena as contribuições, desconta o GDD anterior ao plantio e calcula a soma acumulada.

Requisição de histórico com prazo exato 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"}
    ]
  }'

Requisição da previsão arquivada de 1º de julho

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"}
    ]
  }'

Linhas de exemplo na união entre histórico e previsão:

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

Fontes primárias: documentação NOAA CFSv2 · modelo e inventário CFS FLXF · metodologia USDA NASS · arquivo oficial Crop Progress · método GDD da Iowa State.