Welcome to TorchCrop
Introduction
torchcrop is a fully differentiable reimplementation of the
LINTUL-5 crop growth model (Wolf, 2012).
Every step of the simulation — from sowing to harvest — produces valid
torch.autograd gradients, so mechanistic crop processes can be combined
seamlessly with learnable components (neural residuals, learned stress
responses, parameter networks) and calibrated end-to-end with standard
torch.optim optimizers.
Features
- Differentiable Lintul5 — daily forward-Euler simulation of phenology,
radiation interception, photosynthesis, partitioning, leaf/stem/root
dynamics, water balance, and NPK demand, uptake, and soil availability,
all as
torch.nn.Modules. Supports potential (IOPT=1), water-limited (IOPT=2), and water-and-NPK-limited (IOPT=3/4) production modes, with optional automatic irrigation. - Batch-first — every state, parameter and driver carries a leading
batch dimension
[B, ...]so that many sites, years, or parameter sets can be simulated in parallel on GPU. - 23 bundled crop presets —
torchcrop.available_crops()lists species (wheat, maize, rice, soybean, potato, sugar beet, …); load one viaCropParameters(crop_name="wheat"). - Gradient-based calibration —
torchcrop.calibrationprovides a constraint-aware (bounds, dtype, table-ordinate, ordering), transform-basedCalibrationManagerfor fitting crop parameters to observations. - Hybrid modeling hooks — a
HybridManagerwiring layer accepts declarativeResidualSpecs (seedefault_slots()) to injectNeuralResidualcorrections at named points in the pipeline, plus drop-inLearnedStressFactorandParameterNetmodules. - External irrigation/fertiliser — pass explicit
irrigation: [B, T]andfertilizer: [B, T, 3]schedules tomodel(...), overriding the internal table-driven application on a per-day basis. - Smooth options — stage-based branching (
DVS < 1, maturity, etc.) can be switched between hardtorch.whereand sigmoid blends for second-order smoothness. - Gradient-checked primitives — differentiable AFGEN-style interpolation
and soft FST helpers (
LIMIT,INSW,NOTNUL) passtorch.autograd.gradcheck.
Installation
pip install torchcrop
Quickstart
import torch
import torchcrop
from torchcrop.utils.io import make_constant_weather
weather = make_constant_weather(batch_size=2, n_days=150)
model = torchcrop.Lintul5Model()
output = model(weather, start_doy=60)
print(output.yield_) # [B] final storage-organ biomass (g m-2)
print(output.lai.shape) # [B, T+1] LAI trajectory
print(output.dvs.shape) # [B, T+1] development stage trajectory
Gradient-based parameter calibration
torchcrop.calibration turns bounded crop/soil/site parameters into
optimizable latents, keeping them inside their physical range by
construction:
import torch
from torchcrop import CalibrationManager, Lintul5Model, ParameterSpec
model = Lintul5Model(crop_params=torchcrop.CropParameters().to(dtype=torch.float64)).double()
manager = CalibrationManager(
model, specs=[ParameterSpec(name="crop.scale_factor_rue", bounds=(0.5, 1.5))]
)
optimizer = torch.optim.Adam(manager.parameters(), lr=1e-2)
for _ in range(50):
optimizer.zero_grad()
manager.materialize() # write the current latents into model.crop_params
out = model(weather.to(torch.float64), start_doy=60)
loss = ((out.yield_ - observed_yield) ** 2).mean()
loss.backward()
optimizer.step()
See docs/examples/04_calibration/ for a full worked example.
Hybrid modeling
Inject a neural residual on top of a named point in the mechanistic pipeline
via a declarative ResidualSpec:
from torchcrop.nn import ResidualSpec
model = torchcrop.Lintul5Model(
residual_specs=[
ResidualSpec(
"photosynthesis.gtotal",
"rate_factor",
context=("lai", "dvs", "davtmp", "tranrf", "nstress"),
scale=0.15,
),
],
)
torchcrop.nn.default_slots() returns the recommended catalogue of
observable-tied slots (photosynthesis, water stress, partitioning, leaf
senescence); pass a hand-picked subset rather than the whole list unless
every pathway is observable. All parameters — mechanistic and neural — are
surfaced by model.parameters() and can be optimized jointly.
Package layout
torchcrop/
├── model.py # Lintul5Model(nn.Module)
├── engine.py # SimulationEngine time-stepping loop
├── config.py # RunConfig
├── parameters/ # CropParameters / SoilParameters / SiteParameters
│ # + 23 bundled crop presets (crop_data/*.yaml)
├── drivers/weather.py # WeatherDriver [B, T, C]
├── states/model_state.py # ModelState / DiagnosticState tensor containers
├── processes/ # Biophysical processes (astro, phenology,
│ # irradiation, evapotranspiration,
│ # co2_transpiration, water_balance,
│ # photosynthesis, partitioning, leaf_dynamics,
│ # stem_dynamics, root_dynamics, nutrient_demand,
│ # soil_nutrients, heat_stress, stress)
├── functions/ # Differentiable primitives (AFGEN, FST, smoothing)
├── nn/ # NeuralResidual, LearnedStressFactor, ParameterNet,
│ # HybridManager / ResidualSpec wiring layer
├── calibration/ # CalibrationManager, ParameterSpec,
│ # ConstraintGroup, transforms
└── utils/ # I/O, visualisation, validation helpers
Examples
Worked notebooks under docs/examples/ (rendered into the docs site):
01_potential/— potential production (winter wheat)02_water_limited/— water-limited production (winter wheat)03_water_and_nutrient_limited/— water + N and water + NPK limited production04_calibration/— gradient-based parameter calibration05_hybrid/— hybrid ML residual corrections (reserved, notebook in progress)06_daily_timestep/— low-level, day-by-day API usageothers/data_prep.ipynb— preparing the Brandenburg example dataset
Development
pytest # run the test suite
flake8 torchcrop tests # lint
black torchcrop tests # format
pre-commit run --all-files
References
- Wolf, J. (2012). User guide for LINTUL5. Wageningen UR. https://models.pps.wur.nl/lintul-5-crop-growth-simulation-model-potential-water-limited-n-limited-and-npk-limited-conditions
- WUR-AI. diffWOFOST — Differentiable WOFOST crop model. https://github.com/WUR-AI/diffWOFOST
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file torchcrop-1.1.1.tar.gz.
File metadata
- Download URL: torchcrop-1.1.1.tar.gz
- Upload date:
- Size: 2.2 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
aa91def48433e765976d05223b3227cd43d91a0b2feb8a45827de006e546dbee
|
|
| MD5 |
106972bcd70024cc97d0f7821eb17dcf
|
|
| BLAKE2b-256 |
f24e9de80f04adacfc848b5e45c49df5c7a02e7114caa73f6281d87f6bafa0ef
|
File details
Details for the file torchcrop-1.1.1-py2.py3-none-any.whl.
File metadata
- Download URL: torchcrop-1.1.1-py2.py3-none-any.whl
- Upload date:
- Size: 158.4 kB
- Tags: Python 2, Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
baa4af6a0b8e3135a1d97328e621f07f0a6dcb3895c0634c410bb4e8e60799f8
|
|
| MD5 |
84672df4c6d3da5193033f13115a048d
|
|
| BLAKE2b-256 |
216da853b57b20bdab553f1bc25b5c96060462c2365af18aa10c2f5b0c19dac3
|