Community Foodshed Methodology

This page documents the rules, constants, and academic sources that power the tier assignment, parcel clustering, and yield estimation algorithms.

Data Source Citations

Every third-party dataset used in the algorithm, how the provider requires it to be cited, and the license terms. Last updated: March 2026.

1. National Land Cover Database (NLCD) 2021

Used forLand cover classification (forest, crop, urban, wetland, etc.), impervious surface percentage
GEE AssetUSGS/NLCD_RELEASES/2021_REL/NLCD/2021
DOI10.5066/P9JZ7AO3
LicensePublic domain (U.S. Government work). No restrictions.
SourceUSGS MRLC Consortium
Dewitz, J., 2023, National Land Cover Database (NLCD) 2021 Products: U.S. Geological Survey data release, https://doi.org/10.5066/P9JZ7AO3.

2. Shuttle Radar Topography Mission (SRTM)

Used forElevation (meters), slope (degrees), aspect (compass direction)
GEE AssetUSGS/SRTMGL1_003
DOI (data)10.5067/MEaSUREs/SRTM/SRTMGL1.003
DOI (paper)10.1029/2005RG000183
LicensePublic domain (NASA/USGS). Freely available for any use.
SourceNASA JPL / USGS EROS
NASA JPL. NASA Shuttle Radar Topography Mission Global 1 Arc Second [Data set]. NASA EOSDIS Land Processes DAAC, 2013. https://doi.org/10.5067/MEaSUREs/SRTM/SRTMGL1.003.
Farr, T. G., et al. (2007), The Shuttle Radar Topography Mission, Reviews of Geophysics, 45, RG2004. https://doi.org/10.1029/2005RG000183.

3. POLARIS Soil Properties

Used forSoil pH, clay %, sand %, organic matter %, saturated hydraulic conductivity (ksat) — 30m resolution, 0–5cm depth
DOI10.1029/2018WR022797
LicenseFreely available for research and non-commercial use. Contact authors for commercial use.
SourceDuke University Hydrology Group
Chaney, N. W., et al. (2019). POLARIS Soil Properties: 30-m Probabilistic Maps of Soil Properties Over the Contiguous United States. Water Resources Research, 55(4), 2916–2938. https://doi.org/10.1029/2018WR022797.
POLARIS covers CONUS only. International expansion requires ISRIC SoilGrids.

4. JRC Global Surface Water

Used forFlood occurrence probability (% of time water present), flood recurrence
GEE AssetJRC/GSW1_4/GlobalSurfaceWater
DOI10.1038/nature20584
LicenseCopernicus Programme. Free and open access. Attribution required.
SourceEuropean Commission Joint Research Centre
Pekel, J.-F., Cottam, A., Gorelick, N., & Belward, A. S. (2016). High-resolution mapping of global surface water and its long-term changes. Nature, 540, 418–422. https://doi.org/10.1038/nature20584.

5. PRISM Climate Normals

Used forAnnual precipitation (mm), minimum temperature for USDA hardiness zone, frost-free period, growing degree days
GEE AssetOREGONSTATE/PRISM/Norm91m
LicenseFree to reproduce and distribute with attribution.
SourcePRISM Climate Group, Oregon State University
PRISM Climate Group, Oregon State University, https://prism.oregonstate.edu.
PRISM covers CONUS only. International expansion requires WorldClim + ERA5-Land.

6. U.S. Census Bureau (Decennial 2020, ACS, TIGER/Line)

Used forPopulation, households, demographics (age, income, housing type), block-level geography
LicensePublic domain (U.S. Government work). No restrictions.
SourceU.S. Census Bureau
U.S. Census Bureau, 2020 Census Redistricting Data, P.L. 94-171 Summary File, 2021. https://data.census.gov.
U.S. Census Bureau, American Community Survey 5-Year Estimates, 2022. https://data.census.gov.
U.S. Census Bureau, TIGER/Line Shapefiles, 2020. https://www2.census.gov/geo/tiger/.

7. gNATSGO (Gridded National Soil Survey)

Used forAvailable water storage (soil quality proxy), drainage class, farmland classification
LicensePublic domain (U.S. Government work). No restrictions.
SourceUSDA NRCS
Soil Survey Staff. Gridded National Soil Survey Geographic Database (gNATSGO) for the Conterminous United States. USDA NRCS. Available at https://nrcs.app.box.com/v/soils.
In the alpha build, gNATSGO was not accessible via GEE public catalog. The prod build uses local rasters. CONUS only — international expansion requires SoilGrids.

8. USDA Food Access Research Atlas

Used forFood desert designation (tract-level), food access indicators
LicensePublic domain (U.S. Government work). No restrictions.
SourceUSDA ERS
Economic Research Service (ERS), USDA. Food Access Research Atlas. https://www.ers.usda.gov/data-products/food-access-research-atlas/.

Platforms & Tools

Google Earth Engine

Used forData access, sampling, and processing platform
DOI10.1016/j.rse.2017.06.031
TermsFree for research, education, noncommercial. Commercial use requires license.
SourceGoogle Earth Engine
Gorelick, N., et al. (2017). Google Earth Engine: Planetary-scale geospatial analysis for everyone. Remote Sensing of Environment, 202, 18–27. https://doi.org/10.1016/j.rse.2017.06.031.

H3 Hexagonal Hierarchical Spatial Index

Used forSpatial indexing — all data assigned to H3 resolution-8 hexagons (~3.75 acres each)
LicenseApache License 2.0. Free for any use including commercial.
SourceH3 Docs / GitHub
Uber Technologies, Inc. H3: Hexagonal Hierarchical Geospatial Indexing System. https://h3geo.org/. GitHub: https://github.com/uber/h3.
No published academic paper with DOI. Cite the documentation and GitHub repo.

1. Lot-Size to Tier Mapping

Parcels are classified into production tiers based on their contiguous acreage, NLCD land cover type, and impervious surface percentage.

Tier Description Acreage Range Adjacent LX Hexes NLCD Types Max Impervious
C1 Home Garden 0.25 - 2 acres 1 hex dev_low, dev_med (solo hex, no clustering) 40%
C2 Market Garden 0.5 - 5 acres 2+ hexes dev_open, grassland (clustered open space only) 25%
C3 Smallhold 5 - 40 acres 2 - 10 hexes grassland, pasture, cultivated 15%
C4 Farm 40 - 200 acres 10 - 50 hexes pasture, cultivated 10%
C5 Anchor Farm 200 - 2,000 acres 50+ hexes cultivated, pasture 5%
Each H3 resolution-8 hex is approximately 3.75 acres. Adjacent hexes of compatible NLCD types are clustered into parcels using Union-Find connected components on H3 spatial adjacency. Residential hexes (dev_low, dev_med) are NOT clustered — each home is an independent garden unit, always assigned C1 Home Garden regardless of how many neighbors also garden.
Why residential land doesn't cluster: 81 adjacent suburban hexes sharing the same NLCD type are not one "market garden" — they are 81 separate backyards. Union-Find clustering is only applied to agricultural land and open space (parks, campuses) where contiguous acreage represents actual production-scale land. Market gardens (C2) require real contiguous open space, not aggregated backyards.

Source: SPEC Distributed Portfolio v5 — Tier system based on USDA farm size classifications and Peters et al. (2016) carrying capacity methodology.

2. Method × System Matrix

Each tier assumes specific production systems, methods, skill levels, and loss profiles. These assumptions drive the yield calculations.

Tier System(s) Method Skill Loss Profile Max Portfolio Share
C1 Intensive Garden Raised Bed Intermediate Home Garden (22% loss) 15%
C2 Intensive Garden Biointensive Experienced Home Garden (22% loss) 25%
C3 Intensive Garden 20%, Pasture 40%, Orchard 15%, Row Crop 25% Conventional Experienced Home Garden (22% loss) 30%
C4 Row Crop 50%, Pasture 35%, Intensive Garden 15% Conventional Expert Commercial (31% loss) 20%
C5 Row Crop 65%, Pasture 35% Conventional Expert Commercial (31% loss) 10%

Base Yield by Production System

SystemBase Yield (kcal/acre/yr)Labor (hrs/acre/yr)Years to FullCitation
Intensive Garden2,900,0005001McDougall (2019), CoDyre (2015)
Food Forest2,100,000807Bjorklund (2019)
Silvopasture1,500,000405Silveira (2023)
Pasture800,000201USDA-NASS
Orchard3,500,0002005Lordan (2019)
Row Crop13,718,000101Peters (2016) corn baseline

Method Yield Modifiers

MethodYield ModifierLabor ModifierCitation
Conventional1.0x1.0xBaseline
Biointensive1.3 - 4.0x (by skill)2.0 - 3.0xBeeby (2020), Resoil Foundation (2022)
Square Foot Gardening1.2 - 1.5x0.6xU of Minnesota Extension
No-Dig0.97 - 1.12x (by year)0.40xDowding (2013-2024) 13-year trial
Raised Bed1.5 - 2.0x0.7xDawes Arboretum / OSU Extension
Container0.50 - 0.70x1.75xPulighe (2023)

Skill Level Modifiers

Skill LevelYield ModifierDescription
Beginner0.30xFirst year, learning fundamentals
Intermediate0.65x2-4 years, consistent routine
Experienced0.85x5+ years, succession planting
Expert1.0x8+ years, commercial-grade output

Sources: [8] McDougall (2019), [9] CoDyre (2015), [10] Beeby (2020), [22] Dowding (2013-2024), [23] U of Minnesota Extension, [26] Resoil Foundation (2022).

3. NLCD Compatibility Groups

Adjacent hexes cluster into parcels only if they belong to the same compatibility group AND that group supports clustering. Residential hexes (dev_low, dev_med) are never clustered — each home is its own C1 parcel.

Compatibility GroupNLCD TypesEligible TiersClustering
Agriculturalcultivated, pasture, grasslandC2, C3, C4, C5Union-Find (adjacent same-type hexes form parcels)
Open Spacedev_openC1, C2Union-Find (parks, campuses form parcels)
Residentialdev_low, dev_medC1 onlyNone — each hex = 1 parcel (individual home garden)
Excludedforest, water, wetland, barren, dev_high, shrub--
Forest and shrub land: Currently excluded from clustering because converting forest to agriculture is ecologically destructive. Future iterations may add food forest tiers for existing forested land.

NLCD classification from USGS National Land Cover Database 2021. Compatibility rules from SPEC-300 tessellation design.

4. Effective Acres — Density-Weighted Garden Potential

Effective acres uses a density-weighted garden potential model that combines NLCD land cover type with impervious surface percentage to estimate realistic garden space per hex. For residential hexes, this estimates homes per hex, then garden space per home.

Agricultural Land

garden_potential = hex_acres × (1 - impervious_pct / 100)

Cultivated, pasture, and grassland use the full hex area minus impervious surfaces. Typically 95-100% of 3.75 acres.

Residential Land (NLCD dev_low, dev_med)

homes_per_hex = f(nlcd_type, impervious_pct)
garden_sqft_per_home = max(150, 3500 - impervious_pct × 45)
garden_potential = min(homes × garden_sqft / 43560, max_available)
NLCD TypeImpervious %Est. Homes/HexGarden sqft/HomeGarden AcresOld CalcReduction
dev_low35%~7.5~1,9250.332.447.4×
dev_med70%~20~3500.161.137.0×
dev_open10%~1.3~3,0503.383.381.0×
cultivated2%--3.683.681.0×
Why this matters: The old calculation treated every suburban hex as having 2+ acres of garden potential. In reality, a dense residential hex with 8 houses might have 0.3 acres of actual garden space (patios, yards, setbacks). This 7-15× reduction for suburban hexes prevents overstating C1/C2 production in dense areas.

Demand Weighting

Dense residential hexes also generate demand weight (estimated population × 2.5 persons/household). High-density clusters become demand centers (more mouths to feed), while sparse residential areas become the production base.

Density model uses NLCD 2021 + impervious surface data. Residential density estimates are calibrated heuristics, not census-tract-level data.

5. Livestock Integration — Feed-Land Competition

Livestock is integrated into the expansion loop — not added after it. When a C3+ parcel is activated, livestock potential is calculated alongside plant yield. Pasture animals consume effective acres (feed-land competition), reducing the land available for crops.

Unlock Thresholds

AnimalMin SpaceSpace/HeadUses Pasturekcal/head/yrLabor hrs/head/yr
Laying Hens2,000 sqft14 sqftNo (structures)14,80020
Feeder Pigs0.25 ac0.1 acYes117,12020
Hair Sheep1.5 ac0.4 acYes61,7915
Beef Cattle5 ac2.0 acYes269,00030
Aquaculture0.25 ac54 sqftNo (pond)69510 per 50 fish

Feed-Land Competition Model

max_pasture_acres = effective_acres × 0.30 (30% cap)
plant_acres = effective_acres - pasture_used
total_kcal = plant_yield(plant_acres) + livestock_kcal

Pasture animals (sheep, beef, pigs) consume land from the parcel's effective acres — up to 30%. This means a 20-acre C4 farm allocates at most 6 acres to livestock grazing, leaving 14 acres for crops.

Non-pasture animals (laying hens, aquaculture) use structures or ponds and do not deduct from crop land. Laying hens are capped at 12 (C3), 25 (C4), or 50 (C5) per parcel.

Portfolio Cap Enforcement

Livestock kcal is included in the portfolio cap check. A C3 parcel producing 500K plant kcal + 200K livestock kcal counts as 700K toward the C3 tier cap (30% of target). This prevents livestock from inflating results beyond cap limits.

Stocking rates vary by region (humid East vs. arid West requires 2-20× more acreage per head for beef). The model uses unlock_threshold defaults which are calibrated for humid-temperate conditions. Aquaculture uses a tilapia pond model (200 fish/yr × 1.5 lb × 463 kcal/lb).

Sources: USDA-FDC (nutrition), USDA-NASS (production), ATTRA (small-scale guides), Virginia Tech Extension (sheep), Penn State Extension (housing), Missouri Extension (economics). All citations verified against source PDFs.

6. Reference Designs — 5-Acre Market Farm

1-LX Parcel (3.75 acres effective)

ZoneAcresSystemPrimary Crops
Market Garden1.0BiointensiveTomatoes, greens, herbs, peppers
Orchard0.5Fruit treesPeaches, figs, pecans
Pasture/Poultry1.5Rotational25 laying hens, cover crops
Infrastructure0.75-Barn, wash station, parking, paths

2-LX Parcel (7.5 acres effective)

ZoneAcresSystemPrimary Crops
Market Garden2.0BiointensiveFull vegetable rotation (20+ crops)
Orchard1.0Fruit/nut treesPeaches, pecans, figs, persimmons
Row Crop1.5ConventionalSweet potatoes, corn, dry beans
Pasture2.0Rotational grazing25 hens + 3 sheep
Infrastructure1.0-Barn, cooler, wash station, CSA pickup

3-LX Parcel (11.25 acres effective)

ZoneAcresSystemPrimary Crops
Market Garden3.0BiointensiveFull rotation + succession planting
Orchard/Food Forest2.0Multi-strataFruit trees, berry understory, nitrogen fixers
Row Crop2.0ConventionalSweet potatoes, corn, winter wheat, dry beans
Pasture3.0Silvopasture2 cattle + 25 hens + 3 sheep, scattered trees
Infrastructure1.25-Barn, cold storage, processing, farm stand
These are illustrative layouts for East Texas conditions (USDA Zone 8a, 250 frost-free days, 1,300mm precipitation). Actual layouts vary by parcel shape, existing infrastructure, soil conditions, and operator goals.

7. Yield Calculation Formula

Per-Hex Yield (Liebig's Law — Multiplicative)

phi_hex = beta_slope x beta_drainage x beta_texture x beta_pH x beta_OM x beta_flood

hex_yield = base_system_yield x effective_acres x phi_hex

Stage 2: Aggregation-Level Adjustments (applied during regional rollup, NOT per-hex)

aggregated_yield = SUM(hex_yields) x method_modifier x skill_modifier x loss_factor x season_multiplier
method_modifier, skill_modifier, loss_factor, and season_multiplier are applied during tier/parcel aggregation, not at the individual hex level. The per-hex calculation uses only environmental coefficients (phi_hex) because method and skill are properties of the operator, not the land.

Per-Parcel Yield (Sum of Member Hexes)

parcel_yield = SUM( hex_yield for each hex in parcel )

Regional Portfolio Yield (Capped Tiers)

raw_share[tier] = tier_yield / total_yield
capped_share[tier] = min( raw_share, max_share_of_total )
portfolio_yield = SUM( total_yield x capped_share[tier] for each tier )
The portfolio cap prevents any single tier from dominating the regional food supply. If C5 anchor farms produce 60% of raw yield but are capped at 10%, the excess share is redistributed proportionally to uncapped tiers. This models a diversified, resilient food system.

Yield Variance Disclosure

Important: Same-tier parcels can yield 10× differently based on:
  • Skill level: Beginner (0.30×) vs Expert (1.0×) = 3.3× range
  • Crop focus: Vegetables-only vs calorie-optimized = 1.5-2× range
  • Land quality (phi_hex): Poor soil/slope (0.3) vs optimal (1.0) = 3.3× range
  • Method: Container (0.5×) vs biointensive (4.0×) = 8× range
  • Zone modifier: Zone 3 (0.65×) vs Zone 8 (1.0×) = 1.5× range

Combined worst-to-best case: 0.30 × 0.5 × 0.3 = 0.045× vs 1.0 × 4.0 × 1.0 = 4.0×, a ~90× theoretical range. In practice, the typical range across activated parcels is 5-15× due to correlation between skill and method choice.

Coefficient framework: FAO (1976) Framework for Land Evaluation. Multiplicative model: Liebig's Law of the Minimum.

8. Post-Harvest Loss and Waste

Supply ChainLoss FactorTotal LossUsed By
Commercial (retail chain)0.6931%C4 Farm, C5 Anchor
Home Garden (direct sale)0.7822%C1 Community, C2 Market, C3 Smallhold
Home Garden Expert (preservation)0.8218%Expert-level operators

Source: USDA-ERS LAFA (2011) Loss-Adjusted Food Availability data. Blended factors computed from per-crop retail loss, consumer loss, and inedible share.

8a. Production Methods (Source of Truth: Python Coefficients)

Production method modifiers are hardcoded in foodshed_core_v3.py METHODOLOGIES dict with inline citations. The methods.json file exists for UI display only and is NOT consumed by calculations.

Each method defines: land cover requirements (NLCD types), hard gates (min/max acreage, tree cover), preferred conditions, and a yield key that maps to the YIELD_TABLE for production estimates.

Method Definitions

MethodScaleRequired NLCDFood TypeSkill Required
Market Gardenmicro-smalldev_open, dev_lowvegetablesmedium
Backyard Gardenmicrodev_open, dev_lowvegetableslow
Mushroomsmicroforest_dec, forest_evg, forest_mixfungimedium
Container Gardenmicrodev_open, dev_low, dev_medvegetableslow
Raised Bedmicrodev_open, dev_low, dev_medvegetableslow
Community Gardenmicro-smalldev_open, dev_lowvegetableslow
Row Croplargecultivated, pasturegrainhigh
Orchardmedium-largecultivated, pasture, dev_openfruitmedium
Food Forestsmall-mediumforest types, dev_openmixedhigh
Silvopasturelargeforest, pasture, grasslandmixedhigh
Pasture Rotationlargepasture, grasslandlivestockmedium
Methods are matched to hexes using hard gates (requires) and soft preferences (prefers). A hex must satisfy ALL requires conditions. Prefers conditions improve the match score but are not mandatory.

Method definitions derived from USDA extension publications, ATTRA sustainable agriculture guides, and peer-reviewed field studies. See inline citations in foodshed_core_v3.py METHODOLOGIES dict.

8b. Gardener Skill Level Modifiers (Source of Truth: Python Coefficients)

Skill modifiers are hardcoded in foodshed_core_v3.py SKILL_MODIFIERS dict with inline citations. The skills.json file exists for UI display only and is NOT consumed by calculations.

Skill creates 3-11x yield variance on identical plots. This is the LARGEST source of uncertainty in residential food production estimates.

LevelModifierTypical Yield (lbs/sqft)Used ForCitation
General Population0.100.15L1 community estimatesCoDyre et al. (2015), n=50, Guelph ON
Beginner0.300.45First 1-2 seasons, actively learningConk & Porter (2016) lower quartile
Intermediate0.651.003-5 seasons experienceConk & Porter (2016) median
Experienced0.851.255-10 seasons, succession plantingU of MN upper quartile, CoDyre 7+ years
Expert1.001.5010+ years, optimized systemsConk & Porter (2016) maximum 2.06 lbs/sqft
Critical finding (Feb 2026): General population yields 0.13 lbs/sqft (CoDyre 2015). Expert yields 1.5+ lbs/sqft (MN Master Gardener). That's 11x difference from skill alone. Use "general_population" for L1 community estimates, "beginner" for engaged individuals.

Participation Rate (Survey Penalty)

survey_penalty = max(1.0 - red_flag_count × 0.03, 0.50)

Applied during site assessment. Each red-flag answer reduces yield estimate by 3%, floored at 50%. This captures site-specific risks (contamination, access issues, etc.) that satellite data cannot detect.

CoDyre et al. (2015) doi:10.1016/j.ufug.2014.11.001; Conk & Porter (2016) doi:10.2105/AJPH.2015.302991; University of Minnesota Master Gardener Study (2018-2022).

8c. Data Sources and Lineage

The yield calculation pipeline draws from multiple data sources with a clear hierarchy:

Primary Yield Data

SourceFileWhat It ProvidesUsed By
USDA-NASS, Extension Guides, Knott's Handbookcrops_garden.jsonPer-crop yields (lbs/acre, kcal/acre) for garden-scale productioncaloric_engine.load_crop_data()
USDA stocking rate guides, Extension publicationslivestock.jsonLivestock unlock thresholds, production values, citationsassessment_engine.LIVESTOCK_UNLOCKS
USDA-NASS zone datazone_modifiers.jsonGrowing season adjustments by USDA hardiness zonecaloric_engine.get_zone_modifier()

Constants and Framework (Peters et al. 2016)

WhatValueSourceUsed By
Per capita demand2,150 kcal/dayPeters (2016) p.4Self-sufficiency calculations
ROW_CROP baseline13.7M kcal/acrePeters Table S12 (corn grain)BASE_YIELDS[ROW_CROP]
Diet adjustments0.85-1.15xPeters Table 3DIET_ADJUSTMENTS multipliers
Environmental thresholdsvariesPeters supplementaryDrainage, slope, flood coefficients

Citation Enrichment (Reference Only)

peters_yields.json contains 127 crop yields from Peters et al. (2016) Table S12. These are attached to crop recommendations as reference metadata for transparency but are NOT used as the calculation driver. The actual per-crop kcal/acre values come from crops_garden.json.

Key distinction: crops_garden.json drives actual caloric calculations. Peters et al. (2016) provides the theoretical framework (constants, baselines, environmental coefficients) and citation metadata. Do not conflate the two.

Peters, C.J. et al. (2016). Carrying capacity of U.S. agricultural land: Ten diet scenarios. Elementa: Science of the Anthropocene, 4, 000116. DOI: 10.12952/journal.elementa.000116

10. Future Capabilities

Planned but Not Yet Implemented

  • Computer vision photo analysis: Upload 3 photos of your land, AI estimates sun exposure, tree cover, and existing infrastructure.
  • Sensor integration: IoT soil moisture sensors feed real-time data into yield estimates.
  • Mesh network: Community sensor mesh for hyper-local microclimate data across L0 neighborhoods.
  • Climate adjustment coefficients: Regional climate multipliers (currently, Peters yields are national averages that implicitly include climate variation).
  • Food forest tier: Assign existing forest hexes to food forest production with 7-year establishment curve.

Part 2: Full Coefficient Registry

Every number the algorithm uses, its source paper, and confidence level. Loaded from Section B of foodshed_core_v1.py.

Confidence levels: HIGH peer-reviewed / official data MEDIUM extension / grey literature LOW estimates / extrapolations UNKNOWN needs citation

Loading coefficient registry...

Part 3: Algorithm Reference

Detailed algorithm documentation for the six core computation modules. Source code references included for each section.

10. Site Assessment Pipeline

Source: assessment_engine.py

8-Phase Pipeline

PhaseFunctionDescription
1score_questionsTernary answers: good=1.0, warning=0.5, red_flag=0.0
2aggregate_categoriesWeighted category scores with status assignment
3derive_hex_modifiersSatellite-measured coefficients (soil, slope, flood, sun)
4extract_constraintsCross-reference survey + hex data to identify blockers
5recommend_methodsRank production methods by suitability score
6calculate_yieldCombine area, skill, method, survey, hex, and climate factors
7self_sufficiencyCalculate % of annual caloric needs satisfied
8recommend_cropsFilter crops by constraints + hex conditions

Hex Data Derivation

The system auto-answers 7 survey questions from satellite/soil data:

QuestionHex Field(s)Derivation Logic
Q0: Sun hourstree_pct14 hrs x (1 - tree_pct/100). 0% tree = 14 hrs, 100% = 1 hr
Q1: Aspectaspect_deg135-225 = good (south); 90-270 = warning (E/W); else red
Q2: Tree proximitytree_pct<20% = good; 20-60% = warning; >60% = red
Q4: Pooling/drainagedrainage_classwell/excessive = good; moderate = warning; poor = red
Q6: Floodingflood_riskminimal = good; moderate = warning; high = red
Q9: Soil textureclay_pct, sand_pctLoam (15-40% clay, 30-70% sand) = good; extremes = red
Q13: Slopeslope_deg<5 deg = good; 5-10 deg = warning; >10 deg = red

Yield Formula

annual_kcal = area_sqft
  x base_kcal_per_sqft
  x skill_modifier (0.10 - 1.0x, see Section 8b)
  x method_modifier (raised_bed: 1.75x, no_dig: 1.10x, etc.)
  x survey_penalty (1.0 - 0.03 x red_flag_count, floor 0.5)
  x hex_soil_mod (from calculate_soil_coefficient)
  x hex_slope_mod (from calculate_slope_coefficient)
  x hex_flood_mod (from calculate_flood_coefficient)
  x hex_sun_mod (from tree_pct canopy: 0.45 - 1.00x)
  x season_multiplier
season_multiplier is calculated from frost-free days and crop maturity cycles. It is applied during annual aggregation, not in the per-hex yield formula.
Raised beds and containers dampen native soil penalty by 70% because they use imported soil. See Section 10a for full raised bed bypass and survey-hex dampening details.
Area integrity: area_sqft is capped to the physical land covered by selected hex cells (hex_count x 163,350 sqft), then further reduced by satellite-measured tree canopy coverage (e.g., 65% canopy = only 35% usable). Hex modifiers (soil, slope, flood, sun) may be dampened when user survey answers contradict satellite data. See Section 10a.

Season Multiplier

cycles = min( floor( frost_free_days / (avg_maturity_days + turnaround_days) ), 3 )
Crop FocusMaturity (days)TurnaroundCycle Length
vegetables_only551469 days
mixed_garden851499 days
calorie_focused9514109 days
calorie_optimized10014114 days

Constraint Extraction Rules

Cross-references survey answers with hex data. Hex data can escalate but not downgrade a constraint.

ConstraintSurvey SourceHex Override
sun_limitedQ0, Q2 redtree_pct > 60%
water_limitedQ3 reddrainage = poor/very_poor
flood_concernQ6 redflood_risk != minimal
contamination_riskQ31-Q33 (history)NLCD type via B.14 + impervious > 50%
slope_concernQ13 redslope_deg > 8 deg
poor_soil(inferred)hex soil_modifier < 0.5

Method Ranking Algorithm

Each method starts with a base score of 50 and is adjusted by constraint interactions:

ConstraintBoosted Methods (+)Penalized Methods (-)
contamination_highraised_bed +40, container +30others -20
sun_limitedcontainer +15biointensive -30
water_limitedno_dig +20container -15
flood_concernraised_bed/container +15others -10
poor_soilraised_bed +25, container +20-
large land (>1 ac)conventional/biointensive +20raised -15, container -25
small land (<500 sqft)raised/container/SFG +15conventional/biointensive -10

Returns top 3 viable methods plus all blocked methods. Biointensive is blocked by high contamination and requires full sun.

Source: assessment_engine.py. Contamination thresholds from EPA (400 ppm lead action level).

10a. My Plot: Space Types & Area Integrity

Source: assessment.py SPACE_TYPES + plot_routes.py /api/myplot

Space Type Definitions

The user selects a space type that defines their growing context. Each type has a square-footage range, default area, and constraints on which growing methods are available.

Space TypeMin (sqft)Max (sqft)Default (sqft)Allowed MethodsMin Hexes
Balcony2010050Container-
Patio50200120Container, Raised Bed-
Backyard S2001,000500Raised Bed, No-Dig, Biointensive-
Backyard M1,0005,0002,500Raised Bed, No-Dig, Biointensive, Conventional-
Backyard L5,00020,00010,000Raised Bed, No-Dig, Biointensive, Conventional-
Open Lot (0.5-4 ac)21,780174,24043,560Conventional, No-Dig, Biointensive1
Small Acreage (4-10 ac)174,240435,600217,800Conventional, No-Dig, Biointensive2
Farm (10+ ac)435,6004,356,000871,200Conventional, No-Dig3

Hex-Area Integrity Constraint

When a user selects hex cells on the map, the system constrains which space types are available based on the physical land area those hexes represent. This prevents incoherent configurations (e.g., claiming 20 acres of farmland when only 3.75 acres of satellite data is selected).

hex_area = hex_count x 3.75 acres x 43,560 sqft/acre = hex_count x 163,350 sqft
Hexes SelectedPhysical AreaAvailable Space TypesDisabled Space Types
0 (estimation mode)unboundedAllNone
13.75 ac (163,350 sqft)Balcony through Open LotSmall Acreage, Farm
27.50 ac (326,700 sqft)Balcony through Small AcreageFarm
3+11.25+ ac (490,050+ sqft)AllNone
Why these boundaries: Space type ranges are aligned to hex area multiples. Open Lot tops out at 4 acres (174,240 sqft) so 1 hex (163,350 sqft) fits inside it. Small Acreage starts at 4 acres so it requires 2+ hexes. Farm starts at 10 acres (435,600 sqft) so it requires 3+ hexes (490,050 sqft). If a selected space type becomes invalid after hex deselection, the system auto-downgrades to the largest available type.

Backend Area Cap (Safety Net)

Even if a disallowed space type reaches the backend (e.g., direct API call), the server caps the growing area to the physical hex coverage:

max_area = hex_count x 163,350 sqft
total_area_sqft = min(requested_area, max_area)
user_area = min(user_area, max_area)
Both the total land area (used for question filtering and method ranking) and the cultivated area (used for yield calculation) are independently capped. This is a defense-in-depth measure — the frontend constraint prevents the mismatch; the backend cap catches anything that slips through.

Canopy Area Reduction (Physical Land Exclusion)

When satellite data shows tree canopy coverage on selected hexes, the system reduces the available growing area proportionally. This is a physical geometry reduction, not a yield coefficient. If 65% of the land has trees on it, only 35% is physically plantable — regardless of how productive that 35% might be.

canopy_pct = average tree_pct across selected hexes
usable_fraction = max(1.0 - canopy_pct / 100, 0.05)
effective_area = total_hex_area x usable_fraction
Canopy %Usable LandExample (3 hexes = 11.25 ac)
0% (open field)100%11.25 acres usable
30% (scattered trees)70%7.88 acres usable
65% (dense forest)35%3.94 acres usable
90% (closed canopy)10%1.13 acres usable
95%+ (full forest)5% (floor)0.56 acres usable
Distinct from sun_modifier: Canopy area reduction removes land you cannot plant on (trees physically occupy the space). The sun_modifier (Section 10, yield formula) separately adjusts yield quality on the remaining usable area based on shade from adjacent trees. These are independent — one is quantity of land, the other is quality of light. A 5% floor ensures the system always produces a non-zero estimate even in dense forest, acknowledging that forest gardens, clearings, and understory cultivation are possible.
This reduction is only applied when hex data is available (map selection mode). In estimation mode (no hex selected), no canopy reduction is applied because the user is working with hypothetical area.

Survey-Hex Dampening

When satellite data and user survey answers cover the same environmental factor, the system dampens the satellite penalty based on the user's ground observation. This prevents double-counting and respects the user's direct knowledge of their site.

Hex ModifierOverlapping Survey QuestionsWhat They Measure
sun_modifierQ0 (sun hours), Q2 (tree proximity)Light availability / canopy shading
soil_modifierQ4 (drainage), Q9 (soil texture)Soil quality and workability
flood_modifierQ6 (flooding history)Flood risk
slope_modifierQ13 (slope steepness)Terrain slope
dampening_factor = { good: 0.4, warning: 0.7, red_flag: 1.0 }

dampened_modifier = 1.0 - ((1.0 - raw_hex_modifier) x best_dampening_factor)
How it works: If the user says "full sun" (good answer, factor 0.4) but satellite shows canopy cover (sun_modifier = 0.70), the penalty is dampened: 1.0 - ((1.0 - 0.70) x 0.4) = 0.88 instead of 0.70. The user's ground truth partially overrides satellite data. If the user gives a red_flag answer (factor 1.0), the satellite penalty applies in full — ground truth confirms the problem.

Raised Bed Soil Bypass

When the recommended method is raised_bed or container, the soil modifier penalty is reduced by 70% because imported soil replaces native ground:

soil_mod_adjusted = 1.0 - ((1.0 - soil_mod) x 0.30)
A native soil penalty of 0.40 becomes 0.82 with raised beds. Only 30% of the original penalty survives, reflecting the fact that a raised bed still interacts with subsoil drainage but is largely independent of native soil quality.

Space type boundaries aligned to H3 resolution-8 hex area (3.75 acres). Survey-hex overlap mapping derived from HEX_COVERED_QUESTIONS in assessment.py. Dampening factors are design choices calibrated to balance satellite confidence against user observation.

11. Spatial Clustering (Union-Find)

Source: parcels.py

Algorithm Steps

StepOperationDescription
1classify_hexMap each hex to an NLCD compatibility group
2Separate residentialResidential hexes (dev_low, dev_med) become solo 1-hex parcels — skip Union-Find
3Build Union-FindCreate disjoint set for agricultural + open-space hexes only
4Union adjacentFor each hex, union with same-group H3 neighbors (ring 1)
5Extract componentsCollect connected components from Union-Find
6Normalize IDsUse lexicographically smallest hex_id as stable parcel_id
7Merge solo parcelsAdd residential solo hexes into final parcel set
Why residential hexes skip clustering: Union-Find merges all adjacent same-type hexes into one parcel. For agricultural land this is correct — adjacent fields form one farm. For residential land it produces absurd results: 81 adjacent suburban hexes become one "C2 Market Garden" when they are actually 81 separate backyards. Each home is its own independent growing unit (C1 Home Garden), regardless of how many neighbors also garden.

Compatibility Groups

GroupNLCD TypesEligible TiersClustering
Agriculturalcultivated, pasture, grasslandC2, C3, C4, C5Union-Find (2-50+ hexes)
Open Spacedev_openC1, C2Union-Find (1-2+ hexes)
Residentialdev_low, dev_medC1 onlyNone (each hex = 1 parcel)
Excludedforest, water, wetland, barren, dev_high, shrub--

Performance

Time complexity: O(n x alpha(n)) with path compression and union by rank
Typical workload: 11,547 hexes x 6 neighbors = ~70K operations, under 200ms

Effective Acres

effective_acres = SUM( garden_potential(nlcd, impervious_pct) ) per hex

Uses the density-weighted garden potential model (Section 4). Agricultural land uses simple impervious deduction; residential land estimates homes per hex, then garden sqft per home.

Demand Clustering

Demand hexes are identified using NLCD classification (dev_med/dev_high = definite, dev_low > 35% impervious = likely). Clusters use Haversine distance (accurate at all latitudes) with adaptive radius:

Demand DensityCluster RadiusContext
> 15%2 kmDense metro — tight clusters
5-15%5 kmSuburban — moderate reach
1-5%8 kmSemi-rural — wider for towns
< 1%15 kmRural — catches small towns

Cluster centroids are population-weighted using demand_weight from the Phase 2 density model, not simple geographic averaging.

Tier Assignment

For each parcel, check acreage ranges against eligible tiers for its compatibility group. Checked largest-first (C5 before C1). Must also satisfy minimum hex count.

TierMin AcresMax AcresMin Hexes
C5 Anchor200.02,000.050
C4 Farm40.0200.010
C3 Smallhold5.040.02
C2 Market Garden0.55.02
C1 Home Garden0.252.01
Fallback logic (agricultural + open space only): if a clustered parcel exceeds the max acreage range for its group, it receives the highest eligible tier (e.g., a 500-acre contiguous farm = C5 Anchor). If below minimum, the lowest eligible tier is assigned if effective acres are at least 50% of the threshold. This overflow logic does not affect residential hexes — they are always solo C1 parcels.

Union-Find: Tarjan (1975). H3 adjacency: Uber Engineering H3 resolution 8 hexagonal grid.

12. Portfolio Optimization — Strategy-Dependent Caps

Source: services/simulation.py

Portfolio Caps

Caps prevent any single tier from dominating production. They are design choices (not peer-reviewed parameters) and vary by optimization strategy to match each strategy's objective.

TierDefaultYield/LaborResilienceNetworkRationale
C1 Home15%15%20%25%Network raises for super-cluster activation
C2 Market25%25%20%35%Network raises for residential density
C3 Smallhold30%30%25%30%Resilience tightens for true diversity
C4 Farm20%30%20%20%Yield/labor raise (large farms = efficient)
C5 Anchor10%20%15%10%Yield/labor raise; resilience slightly raises
Livestock kcal counts toward these caps. A C3 parcel with 500K plant kcal + 200K livestock kcal = 700K toward the C3 cap. This prevents livestock from inflating results beyond portfolio limits.

Diversification Score

Shannon entropy H = -SUM( p(tier) × ln(p(tier)) )
Higher entropy = more balanced distribution across tiers

Used by the resilience strategy to score parcels that increase portfolio diversity.

Demand Constants — Two Baselines

Contextkcal/person/yearSourceUsage
Regional foodshed analysis784,750Peters et al. (2016) Elementa 4:000116Simulation, scenarios, foodshed solver
Individual garden self-sufficiency730,000FAO/WHO sedentary adult (2,000 kcal/day)Caloric engine (Grow Food tab)
These are two different baselines for two different questions: "Can our region feed itself?" uses Peters (784,750). "How self-sufficient is my garden?" uses the conservative 730,000. Scenario diets (plant-forward, vegan) derive from Peters with documented reduction factors.

Peters et al. (2016) "Carrying capacity of U.S. agricultural land" Elementa 4:000116, p.4. Portfolio caps: local design decision for production diversity — not derived from academic research.

13. Foodshed Solver

Source: foodshed_solver.py

5 Fixed Scenarios

ScenarioMethodDietParticipationPurpose
1. Current Realityconventionalus_average3%Today's baseline
2. Motivated Communitymixed (50% conv + 50% no_dig)us_average10%Achievable with effort
3. Break-Evensolvedsolved≤ 50%First combo that feeds everyone
4. Mobilizationintensive (raised_bed)reduced_meat25%Diet shift scenario
5. Crisis Responsebiointensiveplant_forward50%Expert gardeners + vegan

Effective kcal/acre

effective_kcal_per_acre = BASE_YIELD (2,900,000)
  x method_modifier
  x skill_modifier
  x diet_efficiency
  x loss_factor

Participation Solver

total_demand = population x annual_kcal_per_person
min_participation = total_demand / (suitable_acres x effective_kcal_per_acre)
Result capped at 100%

Break-Even Finder

Iterates method x diet combos in escalating intensity order (conventional/us_avg first, biointensive/vegan last). Returns the first combination where min_participation ≤ 50%. If none achieve 50%, returns the best combo with achievable=false.

Diet Efficiency Table

DietEfficiency Multiplierkcal/person/yrRationale
us_average1.0x784,750Standard American diet (baseline)
reduced_meat1.3x784,75030% less land per calorie
plant_forward1.6x730,00060% less land per calorie
vegan2.0x700,000100% less land per calorie

Loss Factors by Method

Method CategorySupply ChainLoss FactorTotal Loss
conventionalcommercial0.6931%
mixedhome_garden0.7822%
intensivehome_garden0.7822%
biointensivehome_garden_expert0.8218%

Diet efficiency from Peters et al. (2016). Loss factors from USDA-ERS LAFA (2011).

14. Garden Layout Engine (archived)

This feature is currently archived. The layout engine code is preserved in _archived/draw-plot/garden_layout.py for future re-addition.

Source: _archived/draw-plot/garden_layout.py

Bed Positioning

Beds are arranged within a rectangular plot using a border-inset grid layout:

StepOperation
1Load method config (bed size + path width)
2Calculate usable area (total - 2 ft border on all sides)
3Arrange beds: East-West orientation, spaced by path_width, rows extend North-South
4Return list of bed dicts with (x, y, width, height, label)

Method Bed Dimensions

MethodBed SizePath Width
raised_bed4 x 8 ft2 ft
biointensive5 x 20 ft1.5 ft
no_dig4 x 12 ft1.5 ft
conventional2.5 ft row width2.5 ft spacing (30-inch row)

Crop Assignment

Crops are assigned to beds using round-robin from the recommendation list, with companion planting checks:

Main CropCompanionsAntagonists
Tomatoesbasil, carrots, parsleycabbage, fennel
Cornbeans, squash (Three Sisters)-
Beanscorn, squash, carrotsonions, garlic
Potatoesbeans, corntomatoes, squash

Planting Calendar

Timing is calculated relative to frost dates. Each crop stores:

FieldDescriptionExample (Tomatoes)
direct_sowSeed vs transplant methodfalse (transplant)
start_indoor_weeksWeeks before last frost to start indoors6 weeks
transplant_weeks_afterWeeks after last frost to transplant2 weeks
days_to_harvestMaturity from planting75 days
season"cool" (spring/fall) or "warm" (summer)warm

Materials Calculator

volume_cf = bed_width x bed_length x (depth_inches / 12)
volume_cy = volume_cf / 27
MethodSoil Mix
raised_bed1/3 topsoil + 1/3 compost + 1/3 peat/coco coir
no_digCardboard base + 3-4 inches compost buildup annually
biointensiveDouble-dug native soil + compost integration

Companion planting: Carrots Love Tomatoes (Riotte, 1998). Bed dimensions: Jeavons (2012) biointensive standards.

15. Additional Coefficients

Source: foodshed_core_v1.py — Section C coefficient functions (not covered in B.1-B.17 registry)

Elevation Coefficient (beta_elevation)

Based on adiabatic lapse rate (~6.5 deg C per 1,000m):

Elevation Rangebeta_elevationDescription
0 - 300 m1.00Low elevation
300 - 600 m0.95Moderate
600 - 1,000 m0.85High
1,000 - 1,500 m0.70Mountain
1,500 - 2,000 m0.50High mountain
2,000+ m0.25Alpine

Aspect Coefficient (beta_aspect)

Northern Hemisphere only. South-facing slopes receive maximum solar radiation.

Aspect Rangebeta_aspectExposure
135 - 225 deg (South)1.00Maximum solar
90 - 135 or 225 - 270 deg (SE/SW)0.95Good
45 - 90 or 270 - 315 deg (E/W)0.90Moderate
315 - 360 or 0 - 45 deg (North)0.85Reduced

Farmland Class Coefficient (beta_farmland)

Based on USDA farmland classification system:

Farmland Classbeta_farmlandNotes
Prime1.15Best soils, validated high productivity
Prime if Irrigated1.10Prime quality with water access
Statewide Important1.00Baseline reference
Local Important0.95Locally significant
Marginal0.85Marginal potential
Not Farmland0.70Urban, water, etc.

Complete Expanded Hex Yield Formula

hex_yield_kcal = base_system_yield x area_acres
  x beta_soil (geometric mean of pH, OM, texture, drainage)
  x beta_slope (system-specific thresholds)
  x beta_flood (FEMA recurrence intervals)
  x beta_elevation (adiabatic lapse rate)
  x beta_aspect (solar exposure by orientation)
  x beta_farmland (USDA classification)
  x method_modifier x skill_modifier x loss_factor
Note: method_modifier, skill_modifier, and loss_factor shown here for completeness but are applied at the aggregation stage, not per-hex. The hex-level calculation produces raw environmental yield only. See Section 7 for the two-stage formula.
Composite suitability (FAO classification):
phi_hex = beta_soil x beta_slope x beta_flood

S1 (highly suitable): phi ≥ 0.80  |  S2 (moderate): 0.50 ≤ phi < 0.80  |  S3 (marginal): 0.25 ≤ phi < 0.50  |  N1 (unsuitable): 0.10 ≤ phi < 0.25  |  N2 (permanent): phi < 0.10

Elevation: adiabatic lapse rate (standard atmospheric). Aspect: Northern Hemisphere solar geometry. Farmland: USDA-NRCS Farmland Classification System. FAO classes: FAO (1976) Framework for Land Evaluation.

Community Foodshed Platform — Methodology Reference v3.0
All constants sourced from peer-reviewed literature. Full coefficient registry with confidence levels above.
John 21:17