One field, one Sentinel-2 season. Everything on this page is a measurement or a clearly-labelled derivation of one.
The per-pixel rasters are not on this page. They are one file, to download and attach to this conversation:
https://epicfields.app/s/FSIpzLlUZ4rxQTmbQcHBbA/ai/download — Parquet, 1803 rows.
It cannot be fetched; see The per-pixel data for why, and for a Parquet reader that needs only the Python standard library.
area 18.03 ha (geodesic, WGS84 ellipsoid)
grid EPSG:32610, geotransform 630840.0 10.0 0.0 4217580.0 0.0 -10.0
63 x 80 pixels at 10 m; row 0 is the north edge, col 0 the west edge,
row-major. 1803 pixel centres fall inside the boundary and only those are in the data.
season 2025-10-20 to 2026-10-15
overpasses 86 in the window, 51 produced a usable raster
longest gap 45 days
boundary (EPSG:4326) {"type": "Polygon", "coordinates": [[[-121.502267, 38.092267], [-121.502449, 38.092184], [-121.502757, 38.091902], [-121.503066, 38.091515], [-121.503294, 38.091031], [-121.503718, 38.089758], [-121.503804, 38.089693], [-121.507417, 38.094803], [-121.503697, 38.096101], [-121.501127, 38.09252], [-121.502267, 38.092267]]]}
In the Parquet file the NDVI columns are floating point, already in the range 0 to 1. The division by 255 has been done. The formula below describes how the source raster was encoded upstream and why the resolution is 1/255 — it is not something to apply again. Dividing these values by 255 a second time would put the whole field near 0.0015 and draw a map that looks like bare ground everywhere.
ndvi = stored/255 ; stored = floor(clip(ndvi*255,0,255)) ; true value in [stored/255,(stored+1)/255) ; negative clipped to 0 ; no in-band nodata -- 0 is a measurement, use OBSERVED_MASK An observation the satellite did not return is NaN, never a Parquet null -- test with math.isnan(v), not v is None, and note that NaN poisons a mean. The per-pass scalars below are FLOAT, computed from B04/B08 before any quantisation. The 8-bit figure applies to the per-pixel data only.
believed has three values, not two: yes tested against both neighbours and kept, untested an endpoint with no neighbour on one side so the spike rule could not run, no a spike excluded from aggregates. Filtering on == 'yes' drops the untested endpoints as well as the spikes; != 'no' keeps them. kc is clamp(1.37 * ndvi_mean - 0.086, 0, inf) — a function of field-mean NDVI and nothing else: no crop type, no canopy height, nothing measured on the crop. returned% is the share of in-field pixels the satellite returned, which is not the same as the share classified clear.
date ndvi_mean kc sd p10 median p90 returned% gap believed 2025-10-20 0.75003 0.942 0.1022 0.6078 0.7686 0.8745 100.0 - untested 2025-10-30 0.82324 1.042 0.0710 0.7412 0.8510 0.9137 100.0 10 yes 2025-11-06 0.83567 1.059 0.0589 0.7686 0.8667 0.9137 100.0 7 yes 2025-11-09 0.85808 1.090 0.0573 0.7961 0.8902 0.9373 100.0 3 yes 2025-11-24 0.02912 0.000 0.0138 0.0078 0.0235 0.0431 100.0 15 no 2026-01-08 0.67115 0.833 0.1205 0.4980 0.6706 0.8275 100.0 45 yes 2026-01-13 0.17658 0.156 0.0485 0.1255 0.1608 0.2314 100.0 5 no 2026-02-02 0.65991 0.818 0.1138 0.4902 0.6627 0.7961 100.0 20 yes 2026-02-07 0.69035 0.860 0.1024 0.5255 0.7059 0.8039 100.0 5 yes 2026-02-12 0.78185 0.985 0.0857 0.6510 0.8118 0.8745 100.0 5 yes 2026-02-22 0.46033 0.545 0.0752 0.3584 0.4275 0.5373 100.0 10 yes 2026-02-27 0.41087 0.477 0.0805 0.3216 0.3569 0.4627 100.0 5 yes 2026-03-04 0.43330 0.508 0.0841 0.3294 0.3843 0.4886 100.0 5 yes 2026-03-09 0.44212 0.520 0.0844 0.3294 0.3922 0.4980 100.0 5 yes 2026-03-14 0.48819 0.583 0.0970 0.3490 0.4627 0.5804 100.0 5 yes 2026-03-19 0.59059 0.723 0.1187 0.4118 0.5882 0.7255 100.0 5 yes 2026-03-24 0.69694 0.869 0.1121 0.5373 0.7137 0.8275 100.0 5 yes 2026-04-03 0.84025 1.065 0.0581 0.7647 0.8667 0.9137 100.0 10 yes 2026-04-18 0.86512 1.099 0.0359 0.8314 0.8902 0.9137 100.0 15 yes 2026-04-23 0.88498 1.126 0.0391 0.8588 0.9137 0.9294 100.0 5 yes 2026-04-28 0.86778 1.103 0.0403 0.8416 0.8941 0.9137 100.0 5 yes 2026-05-08 0.44374 0.522 0.0372 0.4000 0.4275 0.4471 100.0 10 yes 2026-05-13 0.55294 0.672 0.0477 0.4980 0.5608 0.6000 100.0 5 yes 2026-05-15 0.56302 0.685 0.0553 0.4980 0.5765 0.6157 100.0 2 yes 2026-05-23 0.71041 0.887 0.0730 0.6510 0.7412 0.7961 100.0 8 yes 2026-06-12 0.15826 0.131 0.0263 0.1255 0.1333 0.1608 100.0 20 yes 2026-06-17 0.14330 0.110 0.0271 0.1137 0.1216 0.1490 100.0 5 yes 2026-06-22 0.14528 0.113 0.0309 0.1137 0.1216 0.1490 100.0 5 yes 2026-06-24 0.15493 0.127 0.0363 0.1153 0.1255 0.1686 100.0 2 yes 2026-06-27 0.17027 0.147 0.0403 0.1216 0.1412 0.1882 100.0 3 yes 2026-07-07 0.17407 0.152 0.0509 0.1255 0.1412 0.1961 100.0 10 yes 2026-07-14 0.18128 0.162 0.0480 0.1333 0.1490 0.2235 100.0 7 yes 2026-07-17 0.17434 0.153 0.0304 0.1333 0.1608 0.1843 100.0 3 yes 2026-07-22 0.14727 0.116 0.0285 0.1137 0.1255 0.1490 100.0 5 yes 2026-07-27 0.16583 0.141 0.0320 0.1255 0.1412 0.1765 100.0 5 yes 2026-08-01 0.16346 0.138 0.0310 0.1255 0.1412 0.1765 100.0 5 yes 2026-08-03 0.17678 0.156 0.0301 0.1412 0.1608 0.1843 100.0 2 yes 2026-08-06 0.18836 0.172 0.0285 0.1490 0.1843 0.2024 100.0 3 yes 2026-08-11 0.26185 0.273 0.0428 0.1961 0.2667 0.3098 100.0 5 yes 2026-08-23 0.57702 0.705 0.1398 0.3647 0.6627 0.7255 100.0 12 yes 2026-08-26 0.62409 0.769 0.1412 0.4133 0.7137 0.7686 100.0 3 yes 2026-08-31 0.60546 0.743 0.1057 0.4549 0.6706 0.7137 100.0 5 yes 2026-09-05 0.71379 0.892 0.1416 0.5145 0.8118 0.8510 100.0 5 yes 2026-09-10 0.73585 0.922 0.1479 0.5373 0.8392 0.8745 100.0 5 yes 2026-09-15 0.74207 0.931 0.1341 0.5702 0.8314 0.8667 100.0 5 yes 2026-09-25 0.76511 0.962 0.1279 0.6078 0.8588 0.8824 100.0 10 yes 2026-09-30 0.76492 0.962 0.1256 0.6157 0.8510 0.8824 100.0 5 yes 2026-10-02 0.75971 0.955 0.1189 0.6235 0.8392 0.8745 100.0 2 yes 2026-10-05 0.73729 0.924 0.1166 0.5961 0.8157 0.8471 100.0 3 yes 2026-10-10 0.78885 0.995 0.1206 0.6439 0.8745 0.8980 100.0 5 yes 2026-10-15 0.77571 0.977 0.1125 0.6392 0.8549 0.8784 100.0 5 untested
Every overpass in the window is counted above; these are the stretches where none produced a usable raster.
from to days 2025-11-09 2025-11-24 15 2025-11-24 2026-01-08 45 2026-01-13 2026-02-02 20 2026-04-03 2026-04-18 15 2026-05-23 2026-06-12 20
Season mean NDVI from the Parquet file, averaged into 6×6-pixel blocks (60 m). A . is a block with no in-field pixels. This is a summary of the per-pixel data, not a substitute for it.
. . . . . 0.46 0.49 . . . . . . . 0.45 0.52 0.54 0.54 . . . . . 0.50 0.52 0.51 0.55 0.55 0.55 0.53 . . . 0.52 0.56 0.55 0.49 0.51 0.54 0.54 0.53 . . . . 0.55 0.54 0.53 0.50 0.55 0.55 0.55 0.53 . . . 0.54 0.55 0.55 0.55 0.55 0.55 0.54 0.55 0.51 . . . 0.54 0.55 0.54 0.56 0.56 0.57 0.56 0.53 . . . 0.51 0.54 0.54 0.56 0.56 0.56 0.55 0.52 . . . . 0.53 0.55 0.56 0.54 0.51 . . . . . . . 0.54 0.55 0.50 0.45 . . . . . . . 0.54 0.54 0.50 . . . . . . . . . 0.54 0.51 . . . . . . . . . 0.56 0.53 . . . . . . . . . . . . . . .
The same blocks, season standard deviation — how much each part of the field moved through the season.
. . . . . 0.26 0.24 . . . . . . . 0.24 0.27 0.28 0.26 . . . . . 0.25 0.27 0.28 0.30 0.30 0.29 0.24 . . . 0.28 0.29 0.29 0.28 0.29 0.30 0.30 0.27 . . . . 0.27 0.29 0.29 0.28 0.30 0.30 0.30 0.27 . . . 0.25 0.28 0.29 0.29 0.30 0.30 0.30 0.29 0.19 . . . 0.26 0.28 0.29 0.30 0.30 0.31 0.30 0.27 . . . 0.25 0.27 0.29 0.30 0.30 0.30 0.28 0.26 . . . . 0.26 0.29 0.29 0.29 0.27 . . . . . . . 0.27 0.29 0.27 0.20 . . . . . . . 0.24 0.28 0.25 . . . . . . . . . 0.26 0.22 . . . . . . . . . 0.20 0.17 . . . . . . . . . . . . . . .
From gridmet, gridded, not measured on this field. et0_short_crop_mm is FAO-56 reference evapotranspiration for a 0.12 m grass reference surface — it is not the crop's water use.
date rain_mm et0_short_crop_mm tmin_c tmax_c 2025-10-20 0.00 2.90 10.85 26.75 2025-10-21 0.00 3.10 10.55 27.75 2025-10-22 0.00 2.10 12.15 20.75 2025-10-23 0.00 2.60 10.55 23.45 2025-10-24 0.00 2.30 10.25 22.15 2025-10-25 0.00 1.20 12.95 19.15 2025-10-26 0.30 1.30 11.35 20.35 2025-10-27 0.00 2.10 8.25 21.25 2025-10-28 0.00 2.20 7.45 23.45 2025-10-29 0.00 2.80 9.45 27.35 2025-10-30 0.00 2.70 9.35 26.35 2025-10-31 0.00 2.70 9.15 25.85 2025-11-01 0.00 2.70 9.25 25.85 2025-11-02 0.00 2.00 9.35 25.85 2025-11-03 0.00 2.50 10.55 23.15 2025-11-04 0.00 1.90 9.15 22.95 2025-11-05 1.70 1.20 11.25 18.75 2025-11-06 0.00 1.60 10.55 21.35 2025-11-07 0.00 1.90 10.15 21.65 2025-11-08 0.00 1.50 8.25 23.35 2025-11-09 0.00 1.80 9.25 25.55 2025-11-10 0.00 1.80 9.15 25.65 2025-11-11 0.00 1.60 8.95 22.35 2025-11-12 2.10 1.40 12.85 19.95 2025-11-13 24.20 0.70 14.05 16.35 2025-11-14 0.00 0.90 10.55 18.05 2025-11-15 10.10 0.80 10.25 18.45 2025-11-16 15.80 0.40 13.15 15.95 2025-11-17 5.90 0.70 7.75 14.45 2025-11-18 0.00 1.10 8.05 16.45 2025-11-19 1.50 1.30 11.25 16.65 2025-11-20 3.50 0.60 7.05 13.75 2025-11-21 0.00 0.90 6.35 14.65 2025-11-22 0.00 0.80 4.75 15.25 2025-11-23 0.00 0.70 6.45 10.65 2025-11-24 0.00 0.90 8.85 11.75 2025-11-25 0.00 0.90 6.85 13.95 2025-11-26 0.00 0.80 6.15 12.75 2025-11-27 0.00 0.80 9.05 9.85 2025-11-28 0.00 0.70 7.95 9.15 2025-11-29 0.00 0.80 8.45 9.55 2025-11-30 0.00 0.80 7.35 8.25 2025-12-01 0.00 0.80 3.65 10.75 2025-12-02 0.00 0.70 3.85 10.15 2025-12-03 0.00 1.60 4.95 17.25 2025-12-04 0.00 0.60 1.95 9.95 2025-12-05 0.00 0.50 2.95 6.95 2025-12-06 0.00 0.60 5.95 7.15 2025-12-07 0.00 0.60 6.35 7.75 2025-12-08 0.00 0.60 6.25 7.75 2025-12-09 0.00 0.60 6.25 7.25 2025-12-10 0.00 0.60 5.95 7.55 2025-12-11 0.00 0.60 5.35 6.75 2025-12-12 0.00 0.60 4.35 6.55 2025-12-13 0.00 0.60 4.05 6.25 2025-12-14 0.00 0.50 4.65 6.25 2025-12-15 0.00 0.50 4.75 6.65 2025-12-16 0.00 0.50 5.75 9.75 2025-12-17 0.00 1.30 7.85 19.25 2025-12-18 0.00 0.90 10.55 15.55 2025-12-19 0.40 0.80 10.75 15.05 2025-12-20 0.00 0.50 12.05 15.15 2025-12-21 1.00 0.80 14.45 18.35 2025-12-22 7.70 0.60 11.65 16.85 2025-12-23 2.90 0.70 10.75 17.95 2025-12-24 10.10 1.30 13.25 16.75 2025-12-25 12.10 1.90 11.55 16.55 2025-12-26 0.00 1.40 8.25 16.05 2025-12-27 0.00 0.70 4.85 12.55 2025-12-28 0.00 0.70 2.25 13.15 2025-12-29 0.00 0.80 2.85 10.85 2025-12-30 0.00 0.80 6.25 8.25 2025-12-31 14.40 0.30 5.45 10.15 2026-01-01 3.90 1.10 9.05 17.05 2026-01-02 1.40 0.90 10.15 16.35 2026-01-03 7.80 1.60 11.15 17.55 2026-01-04 19.80 0.60 9.35 12.35 2026-01-05 5.80 1.10 10.05 14.55 2026-01-06 0.00 1.00 8.35 17.45 2026-01-07 0.00 1.20 7.35 15.85 2026-01-08 0.00 1.70 3.75 13.85 2026-01-09 0.00 1.00 1.65 13.15 2026-01-10 0.00 1.40 0.95 15.05 2026-01-11 0.00 1.20 0.85 15.25 2026-01-12 0.00 1.10 1.45 16.15 2026-01-13 0.00 1.00 0.75 16.35 2026-01-14 0.00 1.00 1.45 15.85 2026-01-15 0.00 1.30 2.45 17.15 2026-01-16 0.00 1.00 2.35 16.55 2026-01-17 0.00 0.70 3.25 11.35 2026-01-18 0.00 0.90 3.45 13.85 2026-01-19 0.00 0.70 3.85 8.95 2026-01-20 0.00 0.70 4.35 9.05 2026-01-21 0.00 0.60 5.95 8.75 2026-01-22 0.00 0.90 3.85 16.05 2026-01-23 0.00 0.60 4.55 8.85 2026-01-24 0.00 1.70 2.45 17.85 2026-01-25 0.00 0.90 2.35 10.25 2026-01-26 0.00 1.00 2.95 14.15 2026-01-27 0.70 1.00 2.85 12.55 2026-01-28 0.00 1.30 5.35 16.15 2026-01-29 0.00 1.10 2.95 16.35 2026-01-30 0.00 1.20 3.75 16.75 2026-01-31 0.00 1.20 4.55 15.65 2026-02-01 0.00 1.50 5.25 19.05 2026-02-02 0.00 1.60 3.95 19.95 2026-02-03 0.00 1.50 5.55 19.15 2026-02-04 0.00 1.80 5.95 19.65 2026-02-05 0.00 1.80 6.35 20.65 2026-02-06 0.00 1.70 8.15 22.65 2026-02-07 0.00 1.80 6.35 20.35 2026-02-08 0.00 1.60 6.65 21.95 2026-02-09 0.00 1.90 7.35 18.05 2026-02-10 2.70 1.00 6.75 14.55 2026-02-11 2.40 1.50 7.85 16.45 2026-02-12 0.00 1.90 7.05 18.65 2026-02-13 0.00 2.10 6.05 19.35 2026-02-14 0.00 1.40 6.45 16.85 2026-02-15 13.60 1.30 8.65 17.25 2026-02-16 19.70 0.70 7.65 11.25 2026-02-17 23.40 0.60 4.75 9.05 2026-02-18 6.20 1.40 3.45 10.15 2026-02-19 3.10 1.90 2.95 12.85 2026-02-20 0.00 1.60 2.35 12.55 2026-02-21 0.00 2.10 3.15 16.15 2026-02-22 0.00 1.80 4.85 20.65 2026-02-23 0.00 1.90 7.15 19.95 2026-02-24 0.00 1.60 13.45 19.95 2026-02-25 0.00 1.10 12.55 20.65 2026-02-26 0.00 2.30 12.05 23.35 2026-02-27 0.00 2.50 11.95 25.25 2026-02-28 0.00 2.50 12.75 25.95 2026-03-01 0.00 2.20 10.65 21.05 2026-03-02 0.00 2.50 7.85 20.25 2026-03-03 0.00 2.90 8.65 22.25 2026-03-04 0.00 3.10 8.05 19.65 2026-03-05 0.00 3.80 7.65 20.15 2026-03-06 0.00 4.20 8.55 22.45 2026-03-07 0.00 3.40 6.15 24.65 2026-03-08 0.00 2.80 7.95 24.85 2026-03-09 0.00 3.20 8.55 25.35 2026-03-10 0.00 3.50 7.85 22.55 2026-03-11 0.00 3.80 7.25 25.25 2026-03-12 0.00 3.40 7.75 26.45 2026-03-13 0.00 3.10 7.65 25.65 2026-03-14 0.00 3.90 9.85 25.55 2026-03-15 0.00 4.30 10.15 28.35 2026-03-16 0.00 3.40 10.25 29.25 2026-03-17 0.00 3.50 11.15 30.95 2026-03-18 0.00 3.70 12.15 31.75 2026-03-19 0.00 4.10 12.45 31.65 2026-03-20 0.00 3.80 12.15 31.65 2026-03-21 0.00 4.10 12.25 29.65 2026-03-22 0.00 4.40 11.75 27.95 2026-03-23 0.00 4.60 11.35 28.25 2026-03-24 0.00 4.60 10.85 29.05 2026-03-25 0.00 4.40 10.45 26.55 2026-03-26 0.00 4.50 10.55 25.65 2026-03-27 0.00 3.80 8.85 27.55 2026-03-28 0.00 4.60 8.35 29.35 2026-03-29 0.00 4.70 11.65 31.25 2026-03-30 0.00 3.70 10.75 26.65 2026-03-31 3.60 2.50 13.25 20.45 2026-04-01 1.70 2.30 10.95 18.55 2026-04-02 0.00 3.60 7.45 19.45 2026-04-03 0.00 4.40 7.15 25.05 2026-04-04 0.00 4.50 7.35 28.55 2026-04-05 0.00 4.60 8.15 30.35 2026-04-06 0.00 4.70 9.45 25.25 2026-04-07 0.00 4.70 9.45 24.55 2026-04-08 0.00 5.20 10.35 28.25 2026-04-09 1.10 4.30 11.75 25.75 2026-04-10 8.10 3.00 12.85 20.05 2026-04-11 14.20 2.50 9.75 19.45 2026-04-12 5.20 2.90 10.35 15.85 2026-04-13 0.00 3.70 8.25 20.25 2026-04-14 0.00 4.20 7.85 21.05 2026-04-15 0.00 3.90 7.75 21.65 2026-04-16 0.00 5.10 8.95 22.15 2026-04-17 0.00 5.30 6.35 24.75 2026-04-18 0.00 4.30 6.05 26.85 2026-04-19 0.00 5.00 7.35 26.25 2026-04-20 19.60 2.10 6.55 23.25 2026-04-21 13.80 2.40 8.75 17.85 2026-04-22 2.10 3.00 8.35 19.85 2026-04-23 0.00 4.90 8.45 24.05 2026-04-24 0.00 4.30 9.05 22.55 2026-04-25 0.00 3.70 9.55 17.75 2026-04-26 0.00 3.80 8.95 18.95 2026-04-27 0.00 4.60 7.45 21.25 2026-04-28 0.00 5.00 7.75 24.85 2026-04-29 0.00 5.70 9.45 27.85 2026-04-30 0.00 5.90 10.95 28.05 2026-05-01 0.00 5.40 11.75 27.45 2026-05-02 0.00 4.40 12.05 22.15 2026-05-03 0.00 4.10 12.85 21.25 2026-05-04 3.70 3.40 11.95 18.75 2026-05-05 0.00 2.70 12.05 18.75 2026-05-06 0.00 5.10 12.55 25.35 2026-05-07 0.00 5.90 11.85 28.35 2026-05-08 0.00 5.70 11.55 27.55 2026-05-09 0.00 6.40 12.25 30.35 2026-05-10 0.00 6.10 11.95 30.65 2026-05-11 0.00 6.40 12.15 34.55 2026-05-12 0.00 6.10 13.75 29.25 2026-05-13 0.00 6.20 12.45 26.35 2026-05-14 0.00 7.20 12.25 31.05 2026-05-15 0.00 8.00 13.15 32.15 2026-05-16 0.00 7.80 13.15 29.15 2026-05-17 0.00 7.40 12.85 25.85 2026-05-18 0.00 8.50 13.35 29.85 2026-05-19 0.00 7.00 12.65 32.35 2026-05-20 0.00 7.20 13.15 34.15 2026-05-21 0.00 7.50 13.05 35.15 2026-05-22 0.00 7.00 12.75 31.35 2026-05-23 0.00 6.00 13.15 26.05 2026-05-24 0.00 5.90 12.95 25.05 2026-05-25 0.00 5.50 12.65 21.85 2026-05-26 0.50 5.50 10.65 21.95 2026-05-27 1.10 5.80 11.35 25.15 2026-05-28 3.80 3.90 12.95 21.35 2026-05-29 0.00 4.30 12.45 23.75 2026-05-30 0.00 6.50 11.95 28.05 2026-05-31 0.00 7.30 12.55 32.15 2026-06-01 0.00 7.60 13.55 34.95 2026-06-02 0.00 7.40 13.85 31.85 2026-06-03 0.00 7.60 13.85 32.35 2026-06-04 0.00 7.90 14.75 33.65 2026-06-05 0.00 8.40 15.85 34.65 2026-06-06 0.00 6.80 12.25 27.15 2026-06-07 0.00 7.40 11.85 30.25 2026-06-08 0.00 6.00 13.35 27.75 2026-06-09 0.00 6.30 15.55 30.55 2026-06-10 0.00 8.70 15.95 36.15 2026-06-11 0.00 9.40 17.75 38.55 2026-06-12 0.00 9.00 16.35 38.05 2026-06-13 0.00 9.00 15.65 37.55 2026-06-14 0.00 7.70 15.85 33.85 2026-06-15 0.00 7.60 15.85 32.15 2026-06-16 0.00 7.30 15.55 31.65 2026-06-17 0.00 7.00 15.45 30.25 2026-06-18 0.00 6.60 15.35 28.05 2026-06-19 0.00 6.10 14.95 25.85 2026-06-20 0.00 6.70 13.55 28.35 2026-06-21 0.00 7.60 13.15 32.45 2026-06-22 0.00 7.80 14.15 32.25 2026-06-23 0.00 7.30 13.95 32.15 2026-06-24 0.00 7.20 14.05 30.35 2026-06-25 0.00 7.20 13.95 28.95 2026-06-26 0.00 5.50 15.25 27.05 2026-06-27 0.00 6.10 13.35 26.75 2026-06-28 0.00 8.20 13.25 30.85 2026-06-29 0.00 8.10 14.15 33.05 2026-06-30 0.00 8.20 13.55 31.85 2026-07-01 0.00 7.40 13.35 30.15 2026-07-02 0.00 7.10 13.55 29.45 2026-07-03 0.00 7.90 13.35 33.85 2026-07-04 0.00 8.20 14.15 34.55 2026-07-05 0.00 6.10 13.85 31.15 2026-07-06 0.00 6.60 13.45 30.25 2026-07-07 0.00 6.20 12.95 26.85 2026-07-08 0.00 7.70 12.65 31.55 2026-07-09 0.00 8.70 13.75 35.35 2026-07-10 0.00 7.90 14.35 32.35 2026-07-11 0.00 8.60 14.55 34.05 2026-07-12 0.00 7.20 19.25 33.75 2026-07-13 0.00 7.60 19.95 32.75 2026-07-14 0.00 8.90 19.15 39.75 2026-07-15 0.00 9.50 18.45 38.85 2026-07-16 0.00 8.90 14.45 33.75 2026-07-17 0.00 8.10 13.95 33.55 2026-07-18 0.00 7.90 15.05 33.55 2026-07-19 0.00 8.20 15.25 34.95 2026-07-20 0.00 7.00 18.25 33.45 2026-07-21 0.00 7.00 19.85 38.65 2026-07-22 0.00 6.60 16.45 29.65 2026-07-23 0.00 7.70 15.65 32.95 2026-07-24 0.00 8.50 16.05 34.25 2026-07-25 0.00 8.90 16.45 34.35 2026-07-26 0.00 8.60 15.05 32.95 2026-07-27 0.00 8.00 14.25 32.75 2026-07-28 0.00 8.80 15.05 35.55 2026-07-29 0.00 8.70 16.25 35.35 2026-07-30 0.00 8.60 15.55 35.25 2026-07-31 0.00 9.10 14.65 37.65 2026-08-01 0.00 9.40 15.75 38.45 2026-08-02 0.00 9.20 17.05 39.75 2026-08-03 0.00 9.40 16.95 41.25 2026-08-04 0.00 8.80 16.25 36.85 2026-08-05 0.00 8.20 16.25 34.95 2026-08-06 0.00 8.00 15.75 35.25 2026-08-07 0.00 6.40 16.65 35.45 2026-08-08 0.00 8.20 16.45 35.75 2026-08-09 0.00 8.20 16.05 37.95 2026-08-10 0.00 7.50 15.15 33.95 2026-08-11 0.00 7.40 14.45 33.05 2026-08-12 0.00 6.60 14.45 31.15 2026-08-13 0.00 5.50 15.05 27.35 2026-08-14 0.00 5.30 14.55 27.05 2026-08-15 0.00 5.80 13.75 29.35 2026-08-16 0.00 6.80 14.25 33.85 2026-08-17 0.00 5.90 14.95 32.45 2026-08-18 0.00 6.80 14.25 34.55 2026-08-19 0.00 7.10 14.55 35.75 2026-08-20 0.00 6.90 14.45 32.85 2026-08-21 0.00 6.60 14.95 32.15 2026-08-22 0.00 7.80 15.35 34.25 2026-08-23 0.00 7.80 16.05 36.85 2026-08-24 0.00 7.70 16.45 34.35 2026-08-25 0.00 7.10 15.95 34.35 2026-08-26 0.00 8.20 16.35 36.25 2026-08-27 0.00 7.10 17.75 34.65 2026-08-28 0.00 3.70 14.75 29.35 2026-08-29 0.00 6.70 12.95 31.75 2026-08-30 0.00 6.40 12.05 31.55 2026-08-31 0.00 5.20 13.05 24.25 2026-09-01 0.00 4.90 13.25 24.95 2026-09-02 0.00 4.50 13.25 26.05 2026-09-03 0.00 2.90 14.05 25.85 2026-09-04 0.00 4.40 12.25 26.05 2026-09-05 0.00 5.60 10.65 28.85 2026-09-06 0.00 5.70 11.25 28.95 2026-09-07 0.00 5.60 11.45 32.55 2026-09-08 0.00 5.70 13.25 36.15 2026-09-09 0.00 7.10 18.45 38.95 2026-09-10 0.00 7.60 17.45 38.45 2026-09-11 0.00 6.60 15.15 32.25 2026-09-12 0.00 6.50 14.55 30.35 2026-09-13 0.00 5.70 13.65 27.75 2026-09-14 0.00 6.30 12.25 31.35 2026-09-15 0.00 6.20 11.45 31.25 2026-09-16 0.00 4.70 12.05 25.85 2026-09-17 0.00 3.90 12.15 24.35 2026-09-18 0.00 5.10 12.35 29.65 2026-09-19 0.00 5.60 12.85 31.25 2026-09-20 0.00 4.40 12.75 26.65 2026-09-21 0.00 4.20 13.65 26.55 2026-09-22 0.00 4.60 12.45 28.15 2026-09-23 0.00 5.00 11.75 33.15 2026-09-24 0.00 6.40 13.95 34.35 2026-09-25 0.00 5.20 11.85 29.15 2026-09-26 0.00 5.00 10.85 29.05 2026-09-27 0.00 4.10 11.65 26.55 2026-09-28 0.00 5.20 11.25 28.45 2026-09-29 0.00 6.50 13.45 34.75 2026-09-30 0.00 6.00 13.35 34.65 2026-10-01 0.00 5.20 13.25 35.35 2026-10-02 0.00 4.10 14.55 33.25 2026-10-03 0.00 5.00 14.95 37.45 2026-10-04 0.00 4.00 16.15 37.25 2026-10-05 0.00 4.20 15.95 37.45 2026-10-06 0.00 5.00 16.05 37.65 2026-10-07 0.00 4.10 18.55 34.95 2026-10-08 0.00 4.90 15.55 37.45 2026-10-09 0.00 3.80 12.95 29.25 2026-10-10 0.00 3.00 8.15 24.25 2026-10-11 0.00 2.90 9.15 25.05 2026-10-12 0.00 2.90 7.85 23.25 2026-10-13 0.00 4.40 6.65 25.85 2026-10-14 0.00 2.90 6.35 27.85 2026-10-15 0.00 4.00 8.55 30.15
The per-pixel rasters are one Parquet file: 1803 rows, one per in-field pixel, by row, col, easting, northing, lon, lat, the season statistics, n_observations, and one column per pass date holding that pixel's NDVI on that date.
Download: https://epicfields.app/s/FSIpzLlUZ4rxQTmbQcHBbA/ai/download
That file cannot be reached by fetching it. Chat fetch tools return text and drop binary bodies, and assistant code sandboxes have no outbound network. The route that does work is for the person reading this to download the file and attach it to the same conversation, where the sandbox can open it directly from disk.
An assistant that cannot fetch the file is not blocked and has no reason to stop. The message that moves this forward is the download URL above, given to the person reading this, with a request to attach the downloaded file here. An attached file is everything required: it sits on the sandbox's own disk, the reader below needs no library and no network, and the compositing, zoning and mapping are work the assistant does from that file rather than work handed back to the person.
Some sandboxes have no Parquet engine. The reader below is the whole dependency: only zlib and struct from the standard library, no pyarrow and no pandas. Writing it to a file in the sandbox is enough. Call columns(path) before reading — the date columns are named after the pass dates and cannot be guessed.
"""Read one column out of an Epic Fields cube Parquet file using the standard
library ONLY -- no pyarrow, no pandas, no fastparquet, no duckdb, no polars.
Parquet is an open format and these files are small and simple: flat schema, no
nesting. This handles exactly the subset the cube writer produces.
TWO ENTRY POINTS:
columns(path) -> the column names, in file order
read_column(path, nm) -> that column's values, in row order
Call `columns` first. Several tables carry names you cannot guess -- notably
pixels_by_pass.parquet, whose columns are the pass DATES ('2026-01-13', and
'2026-05-11_SPIKE' for one the pipeline distrusted).
STRINGS WORK. An earlier version of this reader handled only the fixed-width
physical types, so it raised "physical type 6 unsupported" on every BYTE_ARRAY
column -- which is `date` and `believed` in passes.parquet, `date` and
`interpolated` in derived_daily.parquet, and `date` in weather.parquet. That is
precisely the set you need to know WHICH pass is which and which ones the
pipeline believed, so the fallback route handed back numbers that could not be
placed in time. Fixed.
"""
import ctypes, ctypes.util, struct
# ---- Thrift compact protocol ---------------------------------------------- #
class TC:
def __init__(self, b, i=0): self.b, self.i = b, i
def byte(self):
v = self.b[self.i]; self.i += 1; return v
def varint(self):
r = s = 0
while True:
x = self.byte(); r |= (x & 0x7f) << s; s += 7
if not x & 0x80: return r
def zigzag(self):
n = self.varint(); return (n >> 1) ^ -(n & 1)
def binary(self):
n = self.varint(); v = self.b[self.i:self.i+n]; self.i += n; return v
def struct_(self):
"""Returns {field_id: value}. Enough of the spec for these files."""
out, last = {}, 0
while True:
h = self.byte()
if h == 0: return out # STOP
delta, typ = (h >> 4) & 0x0f, h & 0x0f
fid = last + delta if delta else self.zigzag()
last = fid
out[fid] = self.value(typ)
def value(self, typ):
if typ in (1, 2): return typ == 1 # BOOL_TRUE / BOOL_FALSE
if typ == 3: return self.byte()
if typ in (4, 5, 6): return self.zigzag() # i16 / i32 / i64
if typ == 7: v = struct.unpack('<d', self.b[self.i:self.i+8])[0]; self.i += 8; return v
if typ == 8: return self.binary()
if typ in (9, 10): # LIST / SET
h = self.byte(); n = h >> 4; et = h & 0x0f
if n == 15: n = self.varint()
return [self.value(et) for _ in range(n)]
if typ == 12: return self.struct_()
raise ValueError(f"thrift type {typ} not supported")
def _zstd(raw, size):
"""ZSTD needs a SYSTEM library. It is not always there -- on a stock macOS
python neither find_library('zstd') nor any common soname resolves, and then
this whole fallback route dies. That is why the cube is written with GZIP."""
for nm in (ctypes.util.find_library('zstd'), 'libzstd.so.1', 'libzstd.so',
'libzstd.dylib', 'libzstd.1.dylib'):
if not nm: continue
try: lib = ctypes.CDLL(nm); break
except OSError: continue
else:
raise RuntimeError("no libzstd on this system; a GZIP-written cube "
"needs only the stdlib zlib module")
out = ctypes.create_string_buffer(size)
n = lib.ZSTD_decompress(out, ctypes.c_size_t(size), raw, ctypes.c_size_t(len(raw)))
if n != size: raise RuntimeError(f"zstd returned {n}, wanted {size}")
return out.raw
def _rle_bitpacked(buf, width, count):
"""Parquet's RLE / bit-packed hybrid -- used for dictionary indices."""
out, t = [], TC(buf)
while len(out) < count:
header = t.varint()
if header & 1: # bit-packed
groups = header >> 1
for _ in range(groups):
chunk = t.b[t.i:t.i+width]; t.i += width
bits = int.from_bytes(chunk, 'little')
for k in range(8):
if len(out) < count:
out.append((bits >> (k*width)) & ((1 << width) - 1))
else: # run-length
run = header >> 1
nbytes = (width + 7) // 8
val = int.from_bytes(t.b[t.i:t.i+nbytes], 'little'); t.i += nbytes
out.extend([val] * min(run, count - len(out)))
return out[:count]
#: Parquet physical types this reader understands. There is no INT16: small
#: ints are written as INT32. BYTE_ARRAY (6) is variable-length and so has no
#: struct code -- it gets its own branch in `_plain`.
_FIXED = {1: 'i', 2: 'q', 4: 'f', 5: 'd'}
_BYTE_ARRAY = 6
def _footer(raw):
assert raw[:4] == b'PAR1' and raw[-4:] == b'PAR1', "not a parquet file"
flen = struct.unpack('<I', raw[-8:-4])[0]
return TC(raw, len(raw) - 8 - flen).struct_()
def _plain(buf, n, phys, fmt, wid):
"""PLAIN-encoded values.
A fixed-width type is one struct.unpack. BYTE_ARRAY is a walk: each value is
a 4-byte little-endian length followed by that many bytes. Decoded as UTF-8
because every string this writer emits is a date, a flag or a class name.
"""
if phys == _BYTE_ARRAY:
out, i = [], 0
while len(out) < n and i + 4 <= len(buf):
ln = struct.unpack('<I', buf[i:i+4])[0]; i += 4
out.append(buf[i:i+ln].decode('utf-8', 'replace')); i += ln
return out
return list(struct.unpack(f'<{n}{fmt}', buf[:n*wid]))
def columns(path):
"""The column names in `path`, in file order.
Read this before read_column: pixels_by_pass.parquet names its columns after
the pass dates, so there is nothing to guess from.
"""
schema = _footer(open(path, 'rb').read())[2] # list<SchemaElement>
# Element 0 is the root message ('schema'), not a column.
return [s[4].decode() for s in schema[1:] if 4 in s]
def read_column(path, name):
raw = open(path, 'rb').read()
meta = _footer(raw)
values = []
for rg in meta[4]: # row groups
for col in rg[1]: # column chunks
cm = col[3]
if cm[3][0].decode() != name: # path_in_schema[0]
continue
codec, nvals, phys = cm[4], cm[5], cm[1]
fmt = _FIXED.get(phys)
if fmt is None and phys != _BYTE_ARRAY:
raise RuntimeError(f"physical type {phys} unsupported")
wid = 0 if fmt is None else (8 if fmt in 'qd' else 4)
start = cm[11] if 11 in cm and cm[11] else cm[9] # dict page, else data
pos, dictionary = start, None
while len(values) < nvals:
ph = TC(raw, pos); hdr = ph.struct_(); body = ph.i
usize, csize, ptype = hdr[2], hdr[3], hdr[1]
page = raw[body:body+csize]
# parquet codec enum: 0 UNCOMPRESSED, 1 SNAPPY, 2 GZIP, 6 ZSTD
if codec == 2:
import zlib; page = zlib.decompress(page, 16 + zlib.MAX_WBITS)
elif codec == 6: page = _zstd(page, usize)
elif codec != 0: raise RuntimeError(f"codec {codec} unsupported")
if ptype == 2: # DICTIONARY_PAGE
n = hdr[7][1]
dictionary = _plain(page, n, phys, fmt, wid)
else: # DATA_PAGE v1
dh = hdr[5]; n = dh[1]; enc = dh[2]
# Every column this writer emits is OPTIONAL, so a data page
# always opens with a definition-level block: 4-byte length
# then that many bytes. Skip it and the values follow.
dl = struct.unpack('<I', page[:4])[0]; o = 4 + dl
if enc == 0: # PLAIN
values.extend(_plain(page[o:], n, phys, fmt, wid))
elif enc in (2, 8): # PLAIN_DICTIONARY / RLE_DICT
width = page[o]
idx = _rle_bitpacked(page[o+1:], width, n)
values.extend(dictionary[i] for i in idx)
else: raise RuntimeError(f"encoding {enc} unsupported")
pos = body + csize
return values
if __name__ == "__main__": # a self-check
import sys
for path in sys.argv[1:]:
names = columns(path)
print(f"{path}: {len(names)} columns")
for nm in names:
v = read_column(path, nm)
print(f" {nm:24} {len(v):6} values e.g. {v[:2]}")
The same measurements are also published as plain text, one page per question: https://epicfields.app/s/FSIpzLlUZ4rxQTmbQcHBbA/ai.txt lists them. The column dictionary is at https://epicfields.app/s/ai/schema.json.
This package carries NDVI, not surface reflectance. The upstream pipeline reads B04, B08 and SCL only, so B02/B03/B05/B8A/B11/B12 are absent and NDRE and NDMI CANNOT be derived from anything here: they require the red-edge and SWIR bands, and no function of NDVI yields either.
There is no yield, soil, elevation or irrigation data, and no record of any management event: no sowing, grazing, cutting, spraying, harvest or crop type.
Epic Fields publishes this cube as measurements and clearly-labelled derivations. Any description, diagnosis, recommendation or conclusion drawn from it -- by an AI assistant or by anyone else -- is the work of whoever produced it and not of Epic Fields.
Language models routinely produce fluent, specific and confident statements that the underlying data does not support: dates that are not in the record, events that were never observed, and figures that were never computed. This has already been observed with this data. Every number an assistant cites should be locatable in passes.parquet, weather.parquet or derived_daily.parquet; anything that cannot be found there was not measured here.
Epic Fields makes no warranty of fitness for any purpose and accepts no liability for decisions taken on the basis of this data, or of anything generated from it.
Epic Fields (epicfields.app); Contains modified Copernicus Sentinel data; Weather data from gridMET (Abatzoglou et al. 2013), Climatology Lab, University of Idaho. CC BY 4.0 — a report, chart, map or prescription built on this is an adaptation and must carry this attribution.