AGRS – Agricultural Remote Sensing Library
Description
AGRS is a domain-focused Python library that turns Sentinel-2 imagery into agronomy-ready features for tasks such as yield modeling, stress analysis, and site-specific fertilizer (NPK) recommendation.
Instead of re-implementing STAC queries, cloud filters, band math, and geometry clipping in every project, AGRS provides opinionated, agriculture-centric pipelines:
- Search & fetch Sentinel-2 L2A scenes (via Microsoft Planetary Computer STAC).
- Compute a comprehensive set of classic vegetation, water, moisture, and burn indices.
- Select snapshots using agronomic strategies (fractions of season, specific dates, all scenes, best cloud-free scenes).
- Aggregate to field-level features per index and time-fraction of the season.
- Optionally return per-band statistics (mean, median, percentiles, …) for QA and custom modeling.
- Return tidy
pandas.DataFrameobjects ready to join with yield, NPK, and management tables.
The goal is to maximize value for agricultural ML workflows: field trial analysis, site-specific NPK optimization, and crop monitoring.
Key features
-
Sentinel-2 access
- Microsoft Planetary Computer STAC API.
- Automatic bounding-box search from field geometries (
GeoDataFrame).
-
Band handling
- Automatic band detection (default: all
B*assets) or user-defined band list. - Robust geometry clipping for each field.
- Automatic band detection (default: all
-
Built-in index formulas (Sentinel-2 friendly)
(only computed if required bands are present)- Vegetation / chlorophyll:
NDVI,EVI,EVI2,SAVI,MSAVI,OSAVIGNDVI,VARI,GCINDRE,RECI,ARVIMCARI,MCARI2
- Water / moisture / burn:
NDWI(McFeeters),MNDWINDMI(a.k.a moisture index)NBR,NBR2
- Safe division with NaNs for invalid cases (no hard crashes on zero / missing).
- Vegetation / chlorophyll:
-
Snapshot selection strategies
fractional– nearest scenes to temporal fractions (e.g.[0.3, 0.7]of the season).fixed_date– snapshot closest to a single target date.dates– snapshots closest to a list of key dates.top_n_cloudfree– N scenes with lowesteo:cloud_cover.all– use all scenes betweenstart_dateandend_date.
-
Return modes
return_mode="features"(default):- Field-level aggregated index features (per field, per index, per time-fraction).
return_mode="bands":- Per-field, per-date statistics for each band:
mean,median,min,max,std,p10,p90.
- Per-field, per-date statistics for each band:
return_mode="both":- Tuple
(features_df, bands_df)with both outputs.
- Tuple
-
Field-level aggregation
- For each field and index:
- Aggregation over the selected snapshots with statistics such as
mean,median,min,max,std.
- Aggregation over the selected snapshots with statistics such as
- Uses time fractions to encode position within the season (0–1).
- For each field and index:
Installation
pip install agrs
AGRS requires Python 3.9+ and depends on geopandas, shapely, rasterio, pystac-client, and planetary-computer.
Quick start (features only)
import geopandas as gpd
from shapely.geometry import Point
from agrs.client import s2agc
# 1) Single test field
field_geom = Point(-8.0, 32.0)
fields = gpd.GeoDataFrame(
{"field_id": [1], "geometry": [field_geom]},
crs="EPSG:4326",
)
# 2) Create client
client = s2agc(
source="planetary_computer",
max_cloud=0.2,
)
# 3) Get field-level index features with fractional snapshots (e.g. 30%, 60%, 90%, 100% of season)
features_df = client.get_features(
fields=fields,
field_id_col="field_id",
start_date="2018-10-01",
end_date="2019-06-30",
crop="wheat",
snapshot_strategy="fractional",
fractions=[0.3, 0.6, 0.9, 1.0],
return_mode="features", # default
)
print(features_df.head())
Examples of other behaviours
1. Custom fractional snapshots (e.g. 30% and 70% of season)
features_df = client.get_features(
fields=fields,
field_id_col="field_id",
start_date="2018-10-01",
end_date="2019-06-30",
crop="wheat",
snapshot_strategy="fractional",
fractions=[0.3, 0.7],
return_mode="features",
)
2. Bands only (all snapshots between two dates)
bands_df = client.get_features(
fields=fields,
field_id_col="field_id",
start_date="2018-10-01",
end_date="2019-06-30",
crop="wheat",
snapshot_strategy="all", # use all available scenes
return_mode="bands", # per-band stats per date
)
print(bands_df.head())
3. Features + bands together
features_df, bands_df = client.get_features(
fields=fields,
field_id_col="field_id",
start_date="2018-10-01",
end_date="2019-06-30",
crop="wheat",
snapshot_strategy="dates",
key_dates=["2019-02-15", "2019-04-01"],
return_mode="both",
)
More usage patterns (fixed-date, top-N cloud-free, multi-field examples) are available in the examples/ folder.
Contributing
Contributions, bug reports, and feature requests are very welcome.
Please see CONTRIBUTING.md for guidelines on how to:
- Set up a development environment
- Run tests and examples
- Propose new indices, snapshot strategies, or data sources
- Open issues and pull requests
License
AGRS is released under the MIT License. See LICENSE for details.
Metadata
Release files for agrs 0.1.4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| agrs-0.1.4.tar.gz | 18.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| agrs-0.1.4-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 32.5 kB
Release files / agrs-0.1.4.tar.gz
| Download URL | agrs-0.1.4.tar.gz |
|---|---|
| Size | 18.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ba160bcea1882ace554bc2da26e34bc4e5b5ba3cec3c32278c1c2d6dbc97da0c
|
|
BLAKE2b-256 checksum How to use checksums |
43e2ded860375889be1b6d94e38ab01dd54af1ef7f33aa9c5d4c98821ad82e77
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.13
|
Release files / agrs-0.1.4-py3-none-any.whl
| Download URL | agrs-0.1.4-py3-none-any.whl |
|---|---|
| Size | 14.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
793ea4699f7b5f1565da1dafe4e5e3b4a161a89516783916eaae63ce6d930987
|
|
BLAKE2b-256 checksum How to use checksums |
97adc9110a016ff99f55325b000e29e317d1fa1054732ca7dde5ee11619ff9a7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.13
|