cropforge 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cropforge-0.2.0/PKG-INFO +58 -0
- cropforge-0.2.0/README.md +18 -0
- cropforge-0.2.0/cropforge/__init__.py +31 -0
- cropforge-0.2.0/cropforge/crop.py +77 -0
- cropforge-0.2.0/cropforge/environment.py +3 -0
- cropforge-0.2.0/cropforge/farm.py +725 -0
- cropforge-0.2.0/cropforge/loaders.py +502 -0
- cropforge-0.2.0/cropforge/logger.py +351 -0
- cropforge-0.2.0/cropforge/runtime.py +369 -0
- cropforge-0.2.0/cropforge/state.py +144 -0
- cropforge-0.2.0/cropforge/viz/static/index.html +250 -0
- cropforge-0.2.0/cropforge/viz/static/main.js +644 -0
- cropforge-0.2.0/cropforge.egg-info/PKG-INFO +58 -0
- cropforge-0.2.0/cropforge.egg-info/SOURCES.txt +26 -0
- cropforge-0.2.0/cropforge.egg-info/dependency_links.txt +1 -0
- cropforge-0.2.0/cropforge.egg-info/requires.txt +16 -0
- cropforge-0.2.0/cropforge.egg-info/top_level.txt +1 -0
- cropforge-0.2.0/pyproject.toml +78 -0
- cropforge-0.2.0/setup.cfg +4 -0
- cropforge-0.2.0/tests/test_farm.py +441 -0
- cropforge-0.2.0/tests/test_integration_physics.py +542 -0
- cropforge-0.2.0/tests/test_loaders.py +467 -0
- cropforge-0.2.0/tests/test_logger.py +384 -0
- cropforge-0.2.0/tests/test_maize_scenario.py +337 -0
- cropforge-0.2.0/tests/test_physics_env.py +254 -0
- cropforge-0.2.0/tests/test_physics_soil.py +129 -0
- cropforge-0.2.0/tests/test_runtime.py +566 -0
- cropforge-0.2.0/tests/test_state.py +651 -0
cropforge-0.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cropforge
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Open-source, code-first virtual farm runtime for agricultural researchers.
|
|
5
|
+
Author-email: Saswat Sundar Rath <saswat@example.com>
|
|
6
|
+
Maintainer-email: Saswat Sundar Rath <saswat@example.com>
|
|
7
|
+
License: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/saswat/cropforge
|
|
9
|
+
Project-URL: Documentation, https://cropforge.readthedocs.io
|
|
10
|
+
Project-URL: Repository, https://github.com/saswat/cropforge.git
|
|
11
|
+
Project-URL: Bug Tracker, https://github.com/saswat/cropforge/issues
|
|
12
|
+
Project-URL: Changelog, https://github.com/saswat/cropforge/blob/main/CHANGELOG.md
|
|
13
|
+
Keywords: crop simulation,agriculture,farm runtime,agronomy,plant science,virtual farm,DSSAT,APSIM
|
|
14
|
+
Classifier: Development Status :: 3 - Alpha
|
|
15
|
+
Classifier: Intended Audience :: Science/Research
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
|
|
23
|
+
Classifier: Topic :: Scientific/Engineering :: Visualization
|
|
24
|
+
Requires-Python: >=3.12
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
Requires-Dist: pandas>=2.2
|
|
27
|
+
Requires-Dist: numpy>=1.26
|
|
28
|
+
Requires-Dist: pyarrow>=15.0
|
|
29
|
+
Requires-Dist: fastapi>=0.111
|
|
30
|
+
Requires-Dist: uvicorn[standard]>=0.29
|
|
31
|
+
Requires-Dist: plotly>=5.22
|
|
32
|
+
Requires-Dist: dash>=2.17
|
|
33
|
+
Provides-Extra: dev
|
|
34
|
+
Requires-Dist: pytest>=8.2; extra == "dev"
|
|
35
|
+
Requires-Dist: pytest-cov>=5.0; extra == "dev"
|
|
36
|
+
Requires-Dist: dash[testing]>=2.17; extra == "dev"
|
|
37
|
+
Provides-Extra: docs
|
|
38
|
+
Requires-Dist: mkdocs>=1.5; extra == "docs"
|
|
39
|
+
Requires-Dist: mkdocs-material>=9.5; extra == "docs"
|
|
40
|
+
|
|
41
|
+
# CropForge
|
|
42
|
+
|
|
43
|
+
> Open-source, code-first virtual farm runtime for agricultural researchers.
|
|
44
|
+
|
|
45
|
+
CropForge lets you define a crop simulation entirely in Python. You write the model equations; CropForge handles time-stepping, spatial state management, logging, and visual playback.
|
|
46
|
+
|
|
47
|
+
## What's New in v0.2.0
|
|
48
|
+
* **Opt-In Physics**: Built-in, mathematically verified FAO-56 Penman-Monteith ET0 resolution and Root Impedance models. Enabled via the `@farm.use_physics(et0=True, root_impedance=True)` decorator.
|
|
49
|
+
* **Multi-Field Dashboard**: Compare divergent physical environments and scenarios (GxE) directly in the UI with a new Field Selector Dropdown, filtering Heatmaps, 3D viewport, and Inspector panels per-field, while retaining a unified Time-Series comparative view.
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pip install cropforge
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
See `examples/wheat_basic.py` for a minimal working simulation.
|
|
56
|
+
|
|
57
|
+
## Licence
|
|
58
|
+
MIT — Saswat Sundar Rath, ICAR-IARI Jharkhand, 2026
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# CropForge
|
|
2
|
+
|
|
3
|
+
> Open-source, code-first virtual farm runtime for agricultural researchers.
|
|
4
|
+
|
|
5
|
+
CropForge lets you define a crop simulation entirely in Python. You write the model equations; CropForge handles time-stepping, spatial state management, logging, and visual playback.
|
|
6
|
+
|
|
7
|
+
## What's New in v0.2.0
|
|
8
|
+
* **Opt-In Physics**: Built-in, mathematically verified FAO-56 Penman-Monteith ET0 resolution and Root Impedance models. Enabled via the `@farm.use_physics(et0=True, root_impedance=True)` decorator.
|
|
9
|
+
* **Multi-Field Dashboard**: Compare divergent physical environments and scenarios (GxE) directly in the UI with a new Field Selector Dropdown, filtering Heatmaps, 3D viewport, and Inspector panels per-field, while retaining a unified Time-Series comparative view.
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pip install cropforge
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
See `examples/wheat_basic.py` for a minimal working simulation.
|
|
16
|
+
|
|
17
|
+
## Licence
|
|
18
|
+
MIT — Saswat Sundar Rath, ICAR-IARI Jharkhand, 2026
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CropForge — Virtual Farm Runtime for Agricultural Researchers.
|
|
3
|
+
|
|
4
|
+
Open-source, code-first simulation engine. Researchers write the model;
|
|
5
|
+
CropForge faithfully executes it and visualises the result.
|
|
6
|
+
|
|
7
|
+
Public API (PRD Section 6.1):
|
|
8
|
+
from cropforge import Farm, Field, Crop
|
|
9
|
+
|
|
10
|
+
Maintainer : Saswat Sundar Rath, ICAR-IARI Jharkhand
|
|
11
|
+
Licence : MIT
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
__version__ = "0.2.0"
|
|
15
|
+
|
|
16
|
+
# Core public API — matches `from cropforge import Farm, Field, Crop, Weather, Soil, ...`
|
|
17
|
+
from cropforge.crop import Crop
|
|
18
|
+
from cropforge.farm import Farm, Field
|
|
19
|
+
from cropforge.loaders import Soil, Weather
|
|
20
|
+
from cropforge.runtime import CropForgeStepError, CropForgeVisualizeError
|
|
21
|
+
|
|
22
|
+
__all__ = [
|
|
23
|
+
"Farm",
|
|
24
|
+
"Field",
|
|
25
|
+
"Crop",
|
|
26
|
+
"Weather",
|
|
27
|
+
"Soil",
|
|
28
|
+
"CropForgeStepError",
|
|
29
|
+
"CropForgeVisualizeError",
|
|
30
|
+
"__version__",
|
|
31
|
+
]
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
"""
|
|
2
|
+
cropforge/crop.py
|
|
3
|
+
=================
|
|
4
|
+
Crop metadata class.
|
|
5
|
+
|
|
6
|
+
The ``Crop`` object carries species identity, variety, and sowing calendar.
|
|
7
|
+
It is **not** a model — it holds no physiological equations. The researcher's
|
|
8
|
+
``@farm.step`` functions are the model. ``Crop`` is attached to a ``Field``
|
|
9
|
+
via ``Field.set_crop()`` and made available to step functions through the
|
|
10
|
+
field's state so they can make phenology decisions (e.g. days since sowing).
|
|
11
|
+
|
|
12
|
+
PRD Reference: Section 6.1 — Basic Usage Example.
|
|
13
|
+
|
|
14
|
+
Author : Saswat Sundar Rath, ICAR-IARI Jharkhand
|
|
15
|
+
Licence: MIT
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
20
|
+
from dataclasses import dataclass, field
|
|
21
|
+
from typing import Any, Dict
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclass
|
|
25
|
+
class Crop:
|
|
26
|
+
"""Metadata describing a crop planted in a field.
|
|
27
|
+
|
|
28
|
+
Parameters
|
|
29
|
+
----------
|
|
30
|
+
species:
|
|
31
|
+
Common species name, e.g. ``"wheat"``, ``"maize"``, ``"chickpea"``.
|
|
32
|
+
CropForge imposes no controlled vocabulary — the string is passed
|
|
33
|
+
through to the state log and is entirely researcher-defined.
|
|
34
|
+
variety:
|
|
35
|
+
Cultivar or variety identifier, e.g. ``"HD-2967"``, ``"custom"``.
|
|
36
|
+
Defaults to ``"generic"`` when the researcher does not distinguish
|
|
37
|
+
varieties.
|
|
38
|
+
sowing_doy:
|
|
39
|
+
Calendar day-of-year (1–366) on which sowing occurs. The runtime
|
|
40
|
+
engine uses this to determine when to set ``PlantState.age_days = 0``
|
|
41
|
+
for each plant in the field. Plants are placed in the field on the
|
|
42
|
+
first simulation day whose ``EnvironmentState.doy`` matches or
|
|
43
|
+
exceeds ``sowing_doy``.
|
|
44
|
+
custom:
|
|
45
|
+
Arbitrary researcher-defined crop metadata (e.g. base temperature,
|
|
46
|
+
photoperiod sensitivity). Not used by the engine directly; accessible
|
|
47
|
+
inside step functions via ``field.crop.custom``.
|
|
48
|
+
|
|
49
|
+
Examples
|
|
50
|
+
--------
|
|
51
|
+
>>> crop = Crop(species="wheat", variety="HD-2967", sowing_doy=290)
|
|
52
|
+
>>> crop.species
|
|
53
|
+
'wheat'
|
|
54
|
+
>>> crop.sowing_doy
|
|
55
|
+
290
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
species: str
|
|
59
|
+
variety: str = "generic"
|
|
60
|
+
sowing_doy: int = 1
|
|
61
|
+
|
|
62
|
+
# Extensibility hook — keeps the same pattern as SimulationState objects
|
|
63
|
+
custom: Dict[str, Any] = field(default_factory=dict)
|
|
64
|
+
|
|
65
|
+
def __post_init__(self) -> None:
|
|
66
|
+
if not isinstance(self.species, str) or not self.species.strip():
|
|
67
|
+
raise ValueError("Crop.species must be a non-empty string.")
|
|
68
|
+
if not (1 <= self.sowing_doy <= 366):
|
|
69
|
+
raise ValueError(
|
|
70
|
+
f"Crop.sowing_doy must be between 1 and 366, got {self.sowing_doy}."
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
def __repr__(self) -> str:
|
|
74
|
+
return (
|
|
75
|
+
f"Crop(species={self.species!r}, variety={self.variety!r}, "
|
|
76
|
+
f"sowing_doy={self.sowing_doy})"
|
|
77
|
+
)
|