
CropCore is a desktop analytics pipeline for farm field monitoring. It ingests field boundaries, pulls remote satellite and weather data, runs agronomic analysis, and exports per-field and farm-level reports — all from a single command.
Built for dryland Prairie Canada (Alberta / Saskatchewan / Manitoba). No subscription required for weather or elevation data. Satellite imagery requires a free Copernicus CDSE account.
ThreadPoolExecutor--sd-path# 1. Clone the repository
git clone https://github.com/YOUR_USERNAME/CropCore.git
cd CropCore
# 2. Create and activate a virtual environment
python3 -m venv .venv
source .venv/bin/activate
# 3. Install dependencies
pip install -r requirements.txt
# 4. Set up your API credentials
cp config/config.example.json config/config.json
# Edit config/config.json — add your Copernicus CDSE client ID and secret
# 1. Clone the repository
git clone https://github.com/YOUR_USERNAME/CropCore.git
cd CropCore
# 2. Create and activate a virtual environment
python -m venv .venv
.venv\Scripts\activate
# 3. Install dependencies
pip install -r requirements.txt
# 4. Set up your API credentials
copy config\config.example.json config\config.json
# Edit config\config.json — add your Copernicus CDSE client ID and secret
See the User Manual for a full step-by-step walkthrough including how to create field boundaries in QGIS.
# Run with the console UI (guided)
python run.py
# Or run directly against your data folder
python run.py --sd-path data --debug
# Or use the helper script
chmod +x run.sh && ./run.sh
REM Run with the console UI (guided)
python run.py
REM Or run directly against your data folder
python run.py --sd-path data --debug
REM Or double-click run.bat in File Explorer
Outputs are written to:
| Path | Contents |
|---|---|
data/out/reports/ |
PDFs, HTML reports, text summaries, CSV, weather chart |
data/out/rasters/ |
Clipped NDVI and slope GeoTIFFs |
data/out/gif/ |
NDVI time-lapse GIF (when enabled) |
data/logs/ |
run.log |
Place your field data under data/in/ before running:
data/
in/
boundaries/ <- put boundaries.gpkg or boundaries.shp here (required)
soil/ <- optional soil polygons (GPKG / SHP / GeoJSON)
machine_logs.csv <- optional machine log data
config/
job_config.json <- per-run settings (dates, which APIs to call, alerts)
Don’t have a boundaries file yet? See the QGIS boundary guide in the user manual. A sample boundary is auto-generated on first run if none is found.
The data/ directory is gitignored — your field data stays local.
config/config.json)Copy config/config.example.json to config/config.json and fill in:
| Key | Description |
|---|---|
sentinelhub_client_id |
Copernicus CDSE OAuth client ID |
sentinelhub_client_secret |
Copernicus CDSE OAuth client secret |
cdem_api_key |
Optional — leave empty to use the free SRTM fallback |
soil_layer_path_or_url |
Optional — path or URL to a soil layer; leave empty to auto-use Alberta Open Data |
email_summary |
Optional SMTP settings for a post-run summary email |
Do not commit config/config.json — it is gitignored.
data/config/job_config.json)Controls what each run does. Key fields:
| Field | Description |
|---|---|
name |
Job label used in report filenames |
analysis_level |
"field", "farm", or "both" |
start_date / end_date |
Date range for imagery and weather (YYYY-MM-DD) |
apis.sentinel |
Enable/disable Sentinel-2 NDVI fetch |
apis.cdem |
Enable/disable elevation/slope fetch |
outputs.compute_ndvi_trend |
Enable monthly NDVI trend analysis |
alerts.ndvi_min |
Flag fields with mean NDVI below this value |
alerts.dry_streak_days_max |
Flag when dry streak exceeds this many days |
alerts.stress_index_max |
Flag when stress index exceeds this (0-100) |
See data/config/job_config.example.json for a fully annotated example.
The boundaries.gpkg (or .shp) file supports two optional columns:
| Column | Effect |
|---|---|
name |
Human-readable field name shown in all reports |
crop_type |
Crop label (e.g. Wheat, Canola, Barley) — enables crop-grouped farm summary and yield forecasting |
When crop_type is set to a supported crop, CropCore estimates yield using a peak-NDVI linear regression calibrated for Prairie dryland conditions:
| Crop labels recognised | Model | Typical range |
|---|---|---|
Wheat, Spring Wheat, Durum, CWRS, CPS |
Spring Wheat | ~20-65 bu/ac |
Barley, Malt Barley, Feed Barley |
Barley | ~25-75 bu/ac |
Canola, Rapeseed, Oilseed Rape |
Canola | ~15-45 bu/ac |
Penalty adjustments are applied for dry streaks and within-field NDVI variability. A soil drainage modifier is applied automatically when a soil overlay is present. Results appear in per-field reports, farm overview, and the CSV with a plus/minus 20% confidence interval.
Literature basis: Mkhabela et al. (2011), Potgieter et al. (2017), Peng et al. (2018), Zhong et al. (2019).
Two transparent, rule-based scores (no ML) appear in every report:
Soil polygons can be provided three ways (in priority order):
data/in/soil/ or data/in/soils/soil_layer_path_or_url in config/config.jsonCropCore computes area-weighted dominant soil unit, texture, and drainage class per field, and feeds the drainage class into the yield model.
python -m pytest tests -v
187 tests covering job config, validation, alerts, APIs, HTML reports, yield forecasting, and a full pipeline smoke test.