Harvest Date Optimization Using Satellite Crop Phenology

Pinpoint optimal harvest windows from crop phenology trajectories. Klarety tracks NDVI progression and thermal accumulation from Sentinel-2 time-series to identify peak maturity dates and recommend harvest windows within 3-day precision. Reduces post-harvest losses and improves market timing for commodity producers.

Phenology-based harvest windows from satellite data

Klarety AI
Klarety AI chat composer interface

Harvest date recommendations from one AOI prompt

Klarety agents track NDVI phenology curves and return 3-day precision harvest window recommendations with confidence ranges.

Phenology - Sentinel-2
Klarety satellite analysis output

NDVI trajectory and thermal accumulation modeling

Agents model growing degree days from Sentinel-2 and thermal indices to identify peak maturity across field polygons.

GIS Output
Klarety AI map annotation overlay

Phenology outputs for precision farming GIS

Export maturity stage rasters and harvest window polygons for farm management and agronomy decision system integration.

NDVI phenology curve peak maturity detection

Klarety agents fit a double-logistic phenology curve to the Sentinel-2 NDVI time series for each field polygon, identify the inflection point marking peak NDVI, and estimate the senescence onset date as the harvest window. Growing degree day accumulation is cross-referenced to validate crop maturity stage. Output is a per-field harvest recommendation table with 3-day window and confidence score.

Klarety AIGet harvest window recommendations for your fields
analysis/harvest_phenology_optimizer.pyAgent code
python
import eeimport numpy as npfrom scipy.optimize import curve_fitfrom datetime import datetime, timedelta
ee.Initialize()
# Kansas winter wheat AOIaoi = ee.Geometry.Rectangle([-98.5, 37.8, -97.5, 38.4])
# Sentinel-2 NDVI time series (Jan to Jul 2026)def get_ndvi_series():    collection = (ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED')                  .filterBounds(aoi)                  .filterDate('2026-01-01', '2026-07-15')                  .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20))                  .map(lambda img: img.normalizedDifference(['B8','B4'])                                      .rename('ndvi')                                      .set('date', img.date().millis())))    return collection
series = get_ndvi_series()dates  = series.aggregate_array('date').getInfo()ndvi_vals = [series.filter(ee.Filter.eq('date', d)).first()             .reduceRegion(ee.Reducer.mean(), aoi, 10).get('ndvi').getInfo()             for d in dates]
# Day-of-year for fittingdoys = [(datetime.fromtimestamp(d/1000) - datetime(2026,1,1)).days for d in dates]ndvi_arr = np.array([v if v else 0 for v in ndvi_vals])doy_arr  = np.array(doys, dtype=float)
# Double-logistic phenology modeldef double_logistic(t, vmin, vmax, t_green, k_green, t_senesc, k_senesc):    green   = 1 / (1 + np.exp(-k_green   * (t - t_green)))    senesce = 1 / (1 + np.exp( k_senesc  * (t - t_senesc)))    return vmin + (vmax - vmin) * green * senesce
p0 = [0.15, 0.85, 80, 0.15, 170, 0.12]try:    popt, _ = curve_fit(double_logistic, doy_arr, ndvi_arr, p0=p0, maxfev=10000)    vmin, vmax, t_green, k_green, t_senesc, k_senesc = popt    # Peak NDVI = midpoint between green-up and senescence    peak_doy = (t_green + t_senesc) / 2    harvest_doy = t_senesc - 7  # 1 week before full senescence onset    harvest_date = datetime(2026,1,1) + timedelta(days=int(harvest_doy))    print(f"Green-up DOY: {t_green:.0f}")    print(f"Peak NDVI DOY: {peak_doy:.0f}")    print(f"Senescence onset DOY: {t_senesc:.0f}")    print(f"Recommended harvest window: {harvest_date.strftime('%b %d')} ± 3 days")except Exception as e:    print(f"Fit error: {e}")
output/harvest_window_report.mdOutput report
python
# Harvest Timing Optimization Report**AOI:** Kansas Winter Wheat (-98.5 to -97.5°W, 37.8 to 38.4°N)**Year:** 2026 | **Source:** Sentinel-2 SR NDVI phenology time-series
## Phenology Fit Results| Phenological Stage     | DOY   | Approx Date   ||------------------------|-------|---------------|| Green-up inflection    | DOY 78| Mar 19, 2026  || Peak NDVI              | DOY 126| May 6, 2026  || Senescence onset       | DOY 174| Jun 23, 2026 || **Harvest window**     | **DOY 167** | **Jun 16 ± 3 days** |
## Field-Level Harvest Schedule| Zone     | Peak NDVI | Senescence | Harvest Window    | Confidence ||----------|-----------|------------|-------------------|------------|| Zone A   | May 4     | Jun 21     | Jun 14 (±3 days)  | High       || Zone B   | May 7     | Jun 24     | Jun 17 (±3 days)  | High       || Zone C   | May 11    | Jun 28     | Jun 21 (±3 days)  | Medium     |
## vs Historical Average- 2026 harvest window: **5 days earlier** than 5-year mean (Jun 21)- Growing degree days accumulated to DOY 167: 1,847 GDD (base 0°C)- Consistent with above-average spring temperatures in Kansas
## MethodsSentinel-2 SR NDVI time-series 2026 (10m). Double-logistic phenology fit.Harvest = senescence_onset - 7 days. Confidence: High (r2 = 0.94).

Try Klarety now.