paolog-fbk commited on
Commit
64ab846
·
verified ·
1 Parent(s): ae9e891

Upload folder using huggingface_hub

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitignore +171 -0
  2. README.md +77 -3
  3. __init__.py +4 -0
  4. aquacrop/__init__.py +10 -0
  5. aquacrop/core.py +481 -0
  6. aquacrop/data/CP.dat +0 -0
  7. aquacrop/data/CP.st +12 -0
  8. aquacrop/data/CP_EC-EARTH[CP,RCP45,2021-2040]WG.dat +0 -0
  9. aquacrop/data/CP_EC-EARTH[CP,RCP45,2041-2060]WG.dat +0 -0
  10. aquacrop/data/CP_EC-EARTH[CP,RCP45,2041-2060]WG.st +11 -0
  11. aquacrop/data/CP_EC-EARTH[CP,RCP45,2061-2080]WG.dat +0 -0
  12. aquacrop/data/CP_EC-EARTH[CP,RCP85,2021-2040]WG.dat +0 -0
  13. aquacrop/data/CP_EC-EARTH[CP,RCP85,2041-2060]WG.dat +0 -0
  14. aquacrop/data/CP_EC-EARTH[CP,RCP85,2061-2080]WG.dat +0 -0
  15. aquacrop/data/MaunaLoaCO2.txt +63 -0
  16. aquacrop/data/__init__.py +1 -0
  17. aquacrop/data/brussels_climate.txt +0 -0
  18. aquacrop/data/brussels_future.txt +0 -0
  19. aquacrop/data/cambridge_climate.txt +0 -0
  20. aquacrop/data/champion_climate.txt +0 -0
  21. aquacrop/data/cmip6_woolpit/CanESM5/CanESM5_historical_1995_2014_52.22057_0.8847.csv +0 -0
  22. aquacrop/data/cmip6_woolpit/CanESM5/CanESM5_ssp245_2020_2039_52.22057_0.8847.csv +0 -0
  23. aquacrop/data/cmip6_woolpit/CanESM5/CanESM5_ssp245_2040_2059_52.22057_0.8847.csv +0 -0
  24. aquacrop/data/cmip6_woolpit/CanESM5/CanESM5_ssp245_2060_2079_52.22057_0.8847.csv +0 -0
  25. aquacrop/data/cmip6_woolpit/CanESM5/CanESM5_ssp245_2080_2099_52.22057_0.8847.csv +0 -0
  26. aquacrop/data/cmip6_woolpit/CanESM5/CanESM5_ssp585_2020_2039_52.22057_0.8847.csv +0 -0
  27. aquacrop/data/cmip6_woolpit/CanESM5/CanESM5_ssp585_2040_2059_52.22057_0.8847.csv +0 -0
  28. aquacrop/data/cmip6_woolpit/CanESM5/CanESM5_ssp585_2060_2079_52.22057_0.8847.csv +0 -0
  29. aquacrop/data/cmip6_woolpit/CanESM5/CanESM5_ssp585_2080_2099_52.22057_0.8847.csv +0 -0
  30. aquacrop/data/cmip6_woolpit/MIROC6/MIROC6_historical_1995_2014_52.221142_0.884217.csv +0 -0
  31. aquacrop/data/cmip6_woolpit/MIROC6/MIROC6_ssp245_2020_2039_52.221142_0.884217.csv +0 -0
  32. aquacrop/data/cmip6_woolpit/MIROC6/MIROC6_ssp245_2040_2059_52.221142_0.884217.csv +0 -0
  33. aquacrop/data/cmip6_woolpit/MIROC6/MIROC6_ssp245_2060_2079_52.221142_0.884217.csv +0 -0
  34. aquacrop/data/cmip6_woolpit/MIROC6/MIROC6_ssp245_2080_2099_52.221142_0.884217.csv +0 -0
  35. aquacrop/data/cmip6_woolpit/MIROC6/MIROC6_ssp585_2020_2039_52.221142_0.884217.csv +0 -0
  36. aquacrop/data/cmip6_woolpit/MIROC6/MIROC6_ssp585_2040_2059_52.221142_0.884217.csv +0 -0
  37. aquacrop/data/cmip6_woolpit/MIROC6/MIROC6_ssp585_2060_2079_52.221142_0.884217.csv +0 -0
  38. aquacrop/data/cmip6_woolpit/MIROC6/MIROC6_ssp585_2080_2099_52.221142_0.884217.csv +0 -0
  39. aquacrop/data/cmip6_woolpit/NorESM2-LM/NorESM2-LM_historical_1995_2014_52.220307_0.884914.csv +0 -0
  40. aquacrop/data/cmip6_woolpit/NorESM2-LM/NorESM2-LM_ssp245_2020_2039_52.220307_0.884914.csv +0 -0
  41. aquacrop/data/cmip6_woolpit/NorESM2-LM/NorESM2-LM_ssp245_2040_2059_52.220307_0.884914.csv +0 -0
  42. aquacrop/data/cmip6_woolpit/NorESM2-LM/NorESM2-LM_ssp245_2060_2079_52.220307_0.884914.csv +0 -0
  43. aquacrop/data/cmip6_woolpit/NorESM2-LM/NorESM2-LM_ssp245_2080_2099_52.220307_0.884914.csv +0 -0
  44. aquacrop/data/cmip6_woolpit/NorESM2-LM/NorESM2-LM_ssp585_2020_2039_52.220307_0.884914.csv +0 -0
  45. aquacrop/data/cmip6_woolpit/NorESM2-LM/NorESM2-LM_ssp585_2040_2059_52.220307_0.884914.csv +0 -0
  46. aquacrop/data/cmip6_woolpit/NorESM2-LM/NorESM2-LM_ssp585_2060_2079_52.220307_0.884914.csv +0 -0
  47. aquacrop/data/cmip6_woolpit/NorESM2-LM/NorESM2-LM_ssp585_2080_2099_52.220307_0.884914.csv +0 -0
  48. aquacrop/data/cordoba_climate.txt +0 -0
  49. aquacrop/data/hyderabad_climate.txt +0 -0
  50. aquacrop/data/lincolnshire_climate.txt +0 -0
.gitignore ADDED
@@ -0,0 +1,171 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ##########################
2
+
3
+ # ignore all local configuration
4
+ conf/local/**
5
+ !conf/local/.gitkeep
6
+ .telemetry
7
+
8
+ # ignore potentially sensitive credentials files
9
+ conf/**/*credentials*
10
+
11
+ # ignore everything in the following folders
12
+ data/**
13
+
14
+ # except their sub-folders
15
+ !data/**/
16
+
17
+ # also keep all .gitkeep files
18
+ !.gitkeep
19
+
20
+
21
+ # ignore file based logs
22
+ *.log
23
+
24
+ ##########################
25
+ # Common files
26
+
27
+ # IntelliJ
28
+ .idea/
29
+ *.iml
30
+ out/
31
+ .idea_modules/
32
+
33
+ ### macOS
34
+ *.DS_Store
35
+ .AppleDouble
36
+ .LSOverride
37
+ .Trashes
38
+
39
+ # Vim
40
+ *~
41
+ .*.swo
42
+ .*.swp
43
+
44
+ # emacs
45
+ *~
46
+ \#*\#
47
+ /.emacs.desktop
48
+ /.emacs.desktop.lock
49
+ *.elc
50
+
51
+ # JIRA plugin
52
+ atlassian-ide-plugin.xml
53
+
54
+ # C extensions
55
+ *.so
56
+
57
+ ### Python template
58
+ # Byte-compiled / optimized / DLL files
59
+ __pycache__/
60
+ *.py[cod]
61
+ *$py.class
62
+
63
+ # Distribution / packaging
64
+ .Python
65
+ build/
66
+ develop-eggs/
67
+ dist/
68
+ downloads/
69
+ eggs/
70
+ .eggs/
71
+ lib/
72
+ lib64/
73
+ parts/
74
+ sdist/
75
+ var/
76
+ wheels/
77
+ *.egg-info/
78
+ .installed.cfg
79
+ *.egg
80
+ MANIFEST
81
+
82
+ # PyInstaller
83
+ # Usually these files are written by a python script from a template
84
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
85
+ *.manifest
86
+ *.spec
87
+
88
+ # Installer logs
89
+ pip-log.txt
90
+ pip-delete-this-directory.txt
91
+
92
+ # Unit test / coverage reports
93
+ htmlcov/
94
+ .tox/
95
+ .coverage
96
+ .coverage.*
97
+ .cache
98
+ nosetests.xml
99
+ coverage.xml
100
+ *.cover
101
+ .hypothesis/
102
+
103
+ # Translations
104
+ *.mo
105
+ *.pot
106
+
107
+ # Django stuff:
108
+ *.log
109
+ .static_storage/
110
+ .media/
111
+ local_settings.py
112
+
113
+ # Flask stuff:
114
+ instance/
115
+ .webassets-cache
116
+
117
+ # Scrapy stuff:
118
+ .scrapy
119
+
120
+ # Sphinx documentation
121
+ docs/_build/
122
+
123
+ # PyBuilder
124
+ target/
125
+
126
+ # Jupyter Notebook
127
+ .ipynb_checkpoints
128
+
129
+ # IPython
130
+ .ipython/profile_default/history.sqlite
131
+ .ipython/profile_default/startup/README
132
+
133
+ # pyenv
134
+ .python-version
135
+
136
+ # celery beat schedule file
137
+ celerybeat-schedule
138
+
139
+ # SageMath parsed files
140
+ *.sage.py
141
+
142
+ # Environments
143
+ .env
144
+ .envrc
145
+ .venv
146
+ env/
147
+ venv/
148
+ ENV/
149
+ env.bak/
150
+ venv.bak/
151
+
152
+ # mkdocs documentation
153
+ /site
154
+
155
+ # mypy
156
+ .mypy_cache/
157
+
158
+ # sqlite
159
+ .cache.sqlite
160
+
161
+ # mlflow running logs
162
+ mlruns/
163
+
164
+ # ignore keycloak credentials
165
+ config/keycloak_config.json
166
+
167
+ # ignore copernicus oauth credentials
168
+ config/copernicus_oauth_config.json
169
+
170
+ # lightning logs
171
+ lightning_logs
README.md CHANGED
@@ -1,3 +1,77 @@
1
- ---
2
- license: cc-by-nc-nd-4.0
3
- ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Predictive Irrigation Models
2
+
3
+ This repository contains data preprocessing and analytics pipelines for the distribution of Predictive Irrigation Models, integrating data from field sensors, weather, soil, crop, and remote sensing sources.
4
+
5
+ ## Project Structure
6
+ ```
7
+ predictive_irrigation_models/
8
+ ├── config/
9
+ │ ├── params.yml
10
+ │ ├── xgcast_params.yml
11
+ │ ├── aquacrop_params.yml
12
+ │ └── fieldsensor_irrigator_mapping_anonym.yaml.yml
13
+ ├── pipelines/
14
+ │ ├── __init__.py
15
+ │ ├── aquacrop_preparation_pipeline.py
16
+ │ ├── data_collection_pipeline.py
17
+ │ ├── aquacrop_preparation_pipeline.py
18
+ │ ├── demo_run.py
19
+ │ ├── model_preparation_pipeline.py
20
+ │ ├── preprocessing_pipeline.py
21
+ │ ├── resample_impute_pipeline.py
22
+ │ ├── soilcast_pipeline.py
23
+ │ ├── xgcast_pipeline.py
24
+ │ └── xgcast_run.py
25
+ ├── data/
26
+ │ ├── 03_primary/
27
+ │ ├── 04_model_input/
28
+ │ ├── 05_aquacrop_input/
29
+ │ ├── 05_xgcast_input/
30
+ │ ├── 06_aquacrop_output/
31
+ │ └── 06_xgcast_output/
32
+ ├── tools/
33
+ │ └── ...
34
+ └── README.md
35
+ ```
36
+
37
+ ## Features
38
+
39
+ - **Prefect-based Pipelines:** Modular tasks and flows for data collection, transformation, and saving.
40
+ - **Sensor & Weather Data Integration:** Reads and merges raw sensor and weather data for multiple consortia.
41
+ - **Soil, Crop, and Remote Sensing Data:** Integrates geospatial and tabular data sources.
42
+ - **Automated Testing:** Prefect tasks and flows for validating preprocessing results.
43
+ - **Artifact Logging:** Data summary artifacts for monitoring pipeline outputs.
44
+
45
+ ## Getting Started
46
+
47
+ ### Prerequisites
48
+
49
+ - Python 3.8+
50
+ - [Prefect](https://www.prefect.io/)
51
+ - uv
52
+
53
+ Install dependencies:
54
+ ```uv sync```
55
+
56
+ Configuration
57
+ Edit `config/params.yml` to specify consortia names, data folders, and other parameters.
58
+
59
+ ### Running the Pipeline
60
+
61
+ From the project root, run:
62
+
63
+ ```python -m main```
64
+
65
+ ### Running Tests
66
+ From the project root, run:
67
+
68
+ ```python -m test.test_results```
69
+
70
+ ### Contributing
71
+ Feel free to open issues or submit pull requests for improvements or bug fixes.
72
+
73
+ ### License
74
+ MIT License
75
+
76
+ ### Contact
77
+ For questions or collaboration, please contact the repository owner. ``````
__init__.py ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ """soilcast2
2
+ """
3
+
4
+ __version__ = "0.1"
aquacrop/__init__.py ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ import sys
2
+ if not '-m' in sys.argv:
3
+ from .core import AquaCropModel
4
+ from .entities.soil import Soil
5
+ from .entities.crop import Crop
6
+ from .entities.inititalWaterContent import InitialWaterContent
7
+ from .entities.irrigationManagement import IrrigationManagement
8
+ from .entities.fieldManagement import FieldMngt
9
+ from .entities.groundWater import GroundWater
10
+ from .entities.co2 import CO2
aquacrop/core.py ADDED
@@ -0,0 +1,481 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ This file contains the AquacropModel class that runs the simulation.
3
+ """
4
+ import time
5
+ import datetime
6
+ import os
7
+ import logging
8
+ import warnings
9
+ from typing import Dict, Union, Optional, Tuple, TYPE_CHECKING
10
+
11
+ if TYPE_CHECKING:
12
+ # Important: classes are only imported when types are checked, not in production.
13
+ from pandas import DataFrame
14
+ from aquacrop.entities.clockStruct import ClockStruct
15
+ from aquacrop.entities.co2 import CO2
16
+ from aquacrop.entities.crop import Crop
17
+ from aquacrop.entities.initParamVariables import InitialCondition
18
+ from aquacrop.entities.inititalWaterContent import InitialWaterContent
19
+ from aquacrop.entities.paramStruct import ParamStruct
20
+ from aquacrop.entities.soil import Soil
21
+
22
+
23
+ # pylint: disable=wrong-import-position
24
+ from .entities.co2 import CO2
25
+ from .entities.fieldManagement import FieldMngt
26
+ from .entities.groundWater import GroundWater
27
+ from .entities.irrigationManagement import IrrigationManagement
28
+ from .entities.output import Output
29
+ from .initialize.compute_variables import compute_variables
30
+ from .initialize.create_soil_profile import create_soil_profile
31
+ from .initialize.read_clocks_parameters import read_clock_parameters
32
+ from .initialize.read_field_managment import read_field_management
33
+ from .initialize.read_groundwater_table import read_groundwater_table
34
+ from .initialize.read_irrigation_management import read_irrigation_management
35
+ from .initialize.read_model_initial_conditions import read_model_initial_conditions
36
+ from .initialize.read_model_parameters import read_model_parameters
37
+ from .initialize.read_weather_inputs import read_weather_inputs
38
+ from .timestep.check_if_model_is_finished import check_model_is_finished
39
+ from .timestep.run_single_timestep import solution_single_time_step
40
+ from .timestep.update_time import update_time
41
+ from .timestep.outputs_when_model_is_finished import outputs_when_model_is_finished
42
+
43
+ class AquaCropModel:
44
+ """
45
+ This is the main class of the AquaCrop-OSPy model.
46
+ It is in charge of executing all the operations.
47
+
48
+ Parameters:
49
+
50
+ sim_start_time (str): YYYY/MM/DD, Simulation start date
51
+
52
+ sim_end_time (str): date YYYY/MM/DD, Simulation end date
53
+
54
+ weather_df: daily weather data , created using prepare_weather
55
+
56
+ soil: Soil object contains paramaters and variables of the soil
57
+ used in the simulation
58
+
59
+ crop: Crop object contains Paramaters and variables of the crop used
60
+ in the simulation
61
+
62
+ initial_water_content: Defines water content at start of simulation
63
+
64
+ irrigation_management: Defines irrigation strategy
65
+
66
+ field_management: Defines field management options
67
+
68
+ fallow_field_management: Defines field management options during fallow period
69
+
70
+ groundwater: Stores information on water table parameters
71
+
72
+ co2_concentration: Defines CO2 concentrations
73
+
74
+ off_season: (True) simulate off-season or (False) skip ahead to start of
75
+ next growing season
76
+
77
+
78
+ """
79
+
80
+ # Model parameters
81
+ __steps_are_finished: bool = False # True if all steps of the simulation are done.
82
+ __has_model_executed: bool = False # Determines if the model has been run
83
+ __has_model_finished: bool = False # Determines if the model is finished
84
+ __start_model_execution: float = 0.0 # Time when the execution start
85
+ __end_model_execution: float = 0.0 # Time when the execution end
86
+ # Attributes initialised later
87
+ _clock_struct: "ClockStruct"
88
+ _param_struct: "ParamStruct"
89
+ _init_cond: "InitialCondition"
90
+ _outputs: "Output"
91
+ _weather: "DataFrame"
92
+
93
+ def __init__(
94
+ self,
95
+ sim_start_time: str,
96
+ sim_end_time: str,
97
+ weather_df: "DataFrame",
98
+ soil: "Soil",
99
+ crop: "Crop",
100
+ initial_water_content: "InitialWaterContent",
101
+ irrigation_management: Optional["IrrigationManagement"] = None,
102
+ field_management: Optional["FieldMngt"] = None,
103
+ fallow_field_management: Optional["FieldMngt"] = None,
104
+ groundwater: Optional["GroundWater"] = None,
105
+ co2_concentration: Optional["CO2"] = None,
106
+ off_season: bool=False,
107
+ ) -> None:
108
+
109
+ self.sim_start_time = sim_start_time
110
+ self.sim_end_time = sim_end_time
111
+ self.weather_df = weather_df
112
+ self.soil = soil
113
+ self.crop = crop
114
+ self.initial_water_content = initial_water_content
115
+ self.co2_concentration = co2_concentration
116
+ self.off_season = off_season
117
+
118
+ self.irrigation_management = irrigation_management
119
+ self.field_management = field_management
120
+ self.fallow_field_management = fallow_field_management
121
+ self.groundwater = groundwater
122
+
123
+ if irrigation_management is None:
124
+ self.irrigation_management = IrrigationManagement(irrigation_method=0)
125
+ if field_management is None:
126
+ self.field_management = FieldMngt()
127
+ if fallow_field_management is None:
128
+ self.fallow_field_management = FieldMngt()
129
+ if groundwater is None:
130
+ self.groundwater = GroundWater()
131
+ if co2_concentration is None:
132
+ self.co2_concentration = CO2()
133
+
134
+ @property
135
+ def sim_start_time(self) -> str:
136
+ """
137
+ Return sim start date
138
+ """
139
+ return self._sim_start_time
140
+
141
+ @sim_start_time.setter
142
+ def sim_start_time(self, value: str) -> None:
143
+ """
144
+ Check if sim start date is in a correct format.
145
+ """
146
+
147
+ if _sim_date_format_is_correct(value) is not False:
148
+ self._sim_start_time = value
149
+ else:
150
+ raise ValueError("sim_start_time format must be 'YYYY/MM/DD'")
151
+
152
+ @property
153
+ def sim_end_time(self) -> str:
154
+ """
155
+ Return sim end date
156
+ """
157
+ return self._sim_end_time
158
+
159
+ @sim_end_time.setter
160
+ def sim_end_time(self, value: str) -> None:
161
+ """
162
+ Check if sim end date is in a correct format.
163
+ """
164
+ if _sim_date_format_is_correct(value) is not False:
165
+ self._sim_end_time = value
166
+ else:
167
+ raise ValueError("sim_end_time format must be 'YYYY/MM/DD'")
168
+
169
+ @property
170
+ def weather_df(self) -> "DataFrame":
171
+ """
172
+ Return weather dataframe
173
+ """
174
+ return self._weather_df
175
+
176
+ @weather_df.setter
177
+ def weather_df(self, value: "DataFrame"):
178
+ """
179
+ Check if weather dataframe is in a correct format.
180
+ """
181
+ weather_df_columns = "Date MinTemp MaxTemp Precipitation ReferenceET".split(" ")
182
+ if not all([column in value for column in weather_df_columns]):
183
+ raise ValueError(
184
+ "Error in weather_df format. Check if all the following columns exist "
185
+ + "(Date MinTemp MaxTemp Precipitation ReferenceET)."
186
+ )
187
+
188
+ self._weather_df = value
189
+
190
+ def _initialize(self) -> None:
191
+ """
192
+ Initialise all model variables
193
+ """
194
+
195
+ # Initialize ClockStruct object
196
+ self._clock_struct = read_clock_parameters(
197
+ self.sim_start_time, self.sim_end_time, self.off_season
198
+ )
199
+
200
+ # get _weather data
201
+ self.weather_df = read_weather_inputs(self._clock_struct, self.weather_df)
202
+
203
+ # read model params
204
+ self._clock_struct, self._param_struct = read_model_parameters(
205
+ self._clock_struct, self.soil, self.crop, self.weather_df
206
+ )
207
+
208
+ # read irrigation management
209
+ self._param_struct = read_irrigation_management(
210
+ self._param_struct, self.irrigation_management, self._clock_struct
211
+ )
212
+
213
+ # read field management
214
+ self._param_struct = read_field_management(
215
+ self._param_struct, self.field_management, self.fallow_field_management
216
+ )
217
+
218
+ # read groundwater table
219
+ self._param_struct = read_groundwater_table(
220
+ self._param_struct, self.groundwater, self._clock_struct
221
+ )
222
+
223
+ # Compute additional variables
224
+ self._param_struct.CO2 = self.co2_concentration
225
+ self._param_struct = compute_variables(
226
+ self._param_struct, self.weather_df, self._clock_struct
227
+ )
228
+
229
+ # read, calculate inital conditions
230
+ self._param_struct, self._init_cond = read_model_initial_conditions(
231
+ self._param_struct, self._clock_struct, self.initial_water_content, self.crop
232
+ )
233
+
234
+ self._param_struct = create_soil_profile(self._param_struct)
235
+
236
+ # Outputs results (water_flux, crop_growth, final_stats)
237
+ self._outputs = Output(self._clock_struct.time_span, self._init_cond.th)
238
+
239
+ # save model _weather to _init_cond
240
+ self._weather = self.weather_df.values
241
+
242
+ def run_model(
243
+ self,
244
+ num_steps: int = 1,
245
+ till_termination: bool = False,
246
+ initialize_model: bool = True,
247
+ process_outputs: bool = False,
248
+ ) -> bool:
249
+ """
250
+ This function is responsible for executing the model.
251
+
252
+ Arguments:
253
+
254
+ num_steps: Number of steps (Days) to be executed.
255
+
256
+ till_termination: Run the simulation to completion
257
+
258
+ initialize_model: Whether to initialize the model \
259
+ (i.e., go back to beginning of season)
260
+
261
+ process_outputs: process outputs into dataframe before \
262
+ simulation is finished
263
+
264
+ Returns:
265
+ True if finished
266
+ """
267
+
268
+ if initialize_model:
269
+ self._initialize()
270
+
271
+ if till_termination:
272
+ self.__start_model_execution = time.time()
273
+ while self._clock_struct.model_is_finished is False:
274
+ (
275
+ self._clock_struct,
276
+ self._init_cond,
277
+ self._param_struct,
278
+ self._outputs,
279
+ ) = self._perform_timestep()
280
+ self.__end_model_execution = time.time()
281
+ self.__has_model_executed = True
282
+ self.__has_model_finished = True
283
+ return True
284
+ else:
285
+ if num_steps < 1:
286
+ raise ValueError("num_steps must be equal to or greater than 1.")
287
+ self.__start_model_execution = time.time()
288
+ for i in range(num_steps):
289
+
290
+ if (i == range(num_steps)[-1]) and (process_outputs is True):
291
+ self.__steps_are_finished = True
292
+
293
+ (
294
+ self._clock_struct,
295
+ self._init_cond,
296
+ self._param_struct,
297
+ self._outputs,
298
+ ) = self._perform_timestep()
299
+
300
+ if self._clock_struct.model_is_finished:
301
+ self.__end_model_execution = time.time()
302
+ self.__has_model_executed = True
303
+ self.__has_model_finished = True
304
+ return True
305
+
306
+ self.__end_model_execution = time.time()
307
+ self.__has_model_executed = True
308
+ self.__has_model_finished = False
309
+ return True
310
+
311
+ def _perform_timestep(
312
+ self,
313
+ ) -> Tuple["ClockStruct", "InitialCondition", "ParamStruct", "Output"]:
314
+
315
+ """
316
+ Function to run a single time-step (day) calculation of AquaCrop-OS
317
+ """
318
+
319
+ # extract _weather data for current timestep
320
+ weather_step = _weather_data_current_timestep(
321
+ self._weather, self._clock_struct.time_step_counter
322
+ )
323
+
324
+ # Get model solution_single_time_step
325
+ new_cond, param_struct, outputs = solution_single_time_step(
326
+ self._init_cond,
327
+ self._param_struct,
328
+ self._clock_struct,
329
+ weather_step,
330
+ self._outputs,
331
+ )
332
+
333
+ # Check model termination
334
+ clock_struct = self._clock_struct
335
+ clock_struct.model_is_finished = check_model_is_finished(
336
+ self._clock_struct.step_end_time,
337
+ self._clock_struct.simulation_end_date,
338
+ self._clock_struct.model_is_finished,
339
+ self._clock_struct.season_counter,
340
+ self._clock_struct.n_seasons,
341
+ new_cond.harvest_flag,
342
+ )
343
+
344
+ # Update time step
345
+ clock_struct, _init_cond, param_struct = update_time(
346
+ clock_struct, new_cond, param_struct, self._weather, self.crop
347
+ )
348
+
349
+ # Create _outputsdataframes when model is finished
350
+ final_water_flux_growth_outputs = outputs_when_model_is_finished(
351
+ clock_struct.model_is_finished,
352
+ outputs.water_flux,
353
+ outputs.water_storage,
354
+ outputs.crop_growth,
355
+ self.__steps_are_finished,
356
+ )
357
+
358
+ if final_water_flux_growth_outputs is not False:
359
+ (
360
+ outputs.water_flux,
361
+ outputs.water_storage,
362
+ outputs.crop_growth,
363
+ ) = final_water_flux_growth_outputs
364
+
365
+ return clock_struct, _init_cond, param_struct, outputs
366
+
367
+ def get_simulation_results(self):
368
+ """
369
+ Return all the simulation results
370
+ """
371
+ if self.__has_model_executed:
372
+ if self.__has_model_finished:
373
+ return self._outputs.final_stats
374
+ else:
375
+ return False # If the model is not finished, the results are not generated.
376
+ else:
377
+ raise ValueError(
378
+ "You cannot get results without running the model. "
379
+ + "Please execute the run_model() method."
380
+ )
381
+
382
+ def get_water_storage(self):
383
+ """
384
+ Return water storage in soil results
385
+ """
386
+ if self.__has_model_executed:
387
+ return self._outputs.water_storage
388
+ else:
389
+ raise ValueError(
390
+ "You cannot get results without running the model. "
391
+ + "Please execute the run_model() method."
392
+ )
393
+
394
+ def get_water_flux(self):
395
+ """
396
+ Return water flux results
397
+ """
398
+ if self.__has_model_executed:
399
+ return self._outputs.water_flux
400
+ else:
401
+ raise ValueError(
402
+ "You cannot get results without running the model. "
403
+ + "Please execute the run_model() method."
404
+ )
405
+
406
+ def get_crop_growth(self):
407
+ """
408
+ Return crop growth results
409
+ """
410
+ if self.__has_model_executed:
411
+ return self._outputs.crop_growth
412
+ else:
413
+ raise ValueError(
414
+ "You cannot get results without running the model. "
415
+ + "Please execute the run_model() method."
416
+ )
417
+
418
+ def get_additional_information(self) -> Dict[str, Union[bool, float]]:
419
+ """
420
+ Additional model information.
421
+
422
+ Returns:
423
+ dict: {has_model_finished,execution_time}
424
+
425
+ """
426
+ if self.__has_model_executed:
427
+ return {
428
+ "has_model_finished": self.__has_model_finished,
429
+ "execution_time": self.__end_model_execution
430
+ - self.__start_model_execution,
431
+ }
432
+ else:
433
+ raise ValueError(
434
+ "You cannot get results without running the model. "
435
+ + "Please execute the run_model() method."
436
+ )
437
+
438
+
439
+ def check_iwc_soil_match(iwc_layers: int, soil_layers: int) -> bool:
440
+ """
441
+ This function checks if the number of soil layers is equivalent between the user-specified soil profile and initial water content.
442
+
443
+ Arguments:
444
+ iwc_layers
445
+ soil_layers
446
+
447
+ Return:
448
+ boolean: True if number of layers match
449
+
450
+ """
451
+ if(iwc_layers == soil_layers):
452
+ return True
453
+ else:
454
+ return False
455
+
456
+
457
+
458
+
459
+ def _sim_date_format_is_correct(date: str) -> bool:
460
+ """
461
+ This function checks if the start or end date of the simulation is in the correct format.
462
+
463
+ Arguments:
464
+ date
465
+
466
+ Return:
467
+ boolean: True if the date is correct.
468
+ """
469
+ format_dates_string = "%Y/%m/%d"
470
+ try:
471
+ datetime.datetime.strptime(date, format_dates_string)
472
+ return True
473
+ except ValueError:
474
+ return False
475
+
476
+
477
+ def _weather_data_current_timestep(_weather, time_step_counter):
478
+ """
479
+ Extract _weather data for current timestep
480
+ """
481
+ return _weather[time_step_counter]
aquacrop/data/CP.dat ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/CP.st ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [SITE]
2
+ CP
3
+ [LAT, LON and ALT]
4
+ 40.4 101.73 1072
5
+ [CO2]
6
+ 363.8
7
+ [WEATHER FILES]
8
+ CP.dat
9
+ [FORMAT]
10
+ YEAR JDAY MAX MIN RAIN RAD
11
+ [END]
12
+
aquacrop/data/CP_EC-EARTH[CP,RCP45,2021-2040]WG.dat ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/CP_EC-EARTH[CP,RCP45,2041-2060]WG.dat ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/CP_EC-EARTH[CP,RCP45,2041-2060]WG.st ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [SITE]
2
+ CP_EC-EARTH[CP,RCP45,2041-2060]WG
3
+ [LAT, LON and ALT]
4
+ 40.40 101.73 1072.00
5
+ [CO2]
6
+ 487.0
7
+ [WEATHER FILES]
8
+ CP_EC-EARTH[CP,RCP45,2041-2060]WG.dat
9
+ [FORMAT]
10
+ YEAR JDAY MIN MAX RAIN RAD
11
+ [END]
aquacrop/data/CP_EC-EARTH[CP,RCP45,2061-2080]WG.dat ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/CP_EC-EARTH[CP,RCP85,2021-2040]WG.dat ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/CP_EC-EARTH[CP,RCP85,2041-2060]WG.dat ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/CP_EC-EARTH[CP,RCP85,2061-2080]WG.dat ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/MaunaLoaCO2.txt ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ %% ---- Manua Loa observations 1959-2009 & IPCC projections for A1B scenario with BERN model ---- %%
2
+ Year CO2(ppm)
3
+ 1959 315.98
4
+ 1960 316.91
5
+ 1961 317.64
6
+ 1962 318.45
7
+ 1963 318.99
8
+ 1964 319.62
9
+ 1965 320.04
10
+ 1966 321.38
11
+ 1967 322.16
12
+ 1968 323.04
13
+ 1969 324.62
14
+ 1970 325.68
15
+ 1971 326.32
16
+ 1972 327.45
17
+ 1973 329.68
18
+ 1974 330.17
19
+ 1975 331.08
20
+ 1976 332.05
21
+ 1977 333.78
22
+ 1978 335.41
23
+ 1979 336.78
24
+ 1980 338.68
25
+ 1981 340.11
26
+ 1982 341.22
27
+ 1983 342.84
28
+ 1984 344.41
29
+ 1985 345.87
30
+ 1986 347.19
31
+ 1987 348.98
32
+ 1988 351.45
33
+ 1989 352.9
34
+ 1990 354.16
35
+ 1991 355.48
36
+ 1992 356.27
37
+ 1993 356.95
38
+ 1994 358.64
39
+ 1995 360.62
40
+ 1996 362.36
41
+ 1997 363.47
42
+ 1998 366.5
43
+ 1999 368.14
44
+ 2000 369.4
45
+ 2001 371.07
46
+ 2002 373.17
47
+ 2003 375.78
48
+ 2004 377.52
49
+ 2005 379.76
50
+ 2006 381.85
51
+ 2007 383.71
52
+ 2008 385.57
53
+ 2009 387.35
54
+ 2010 388
55
+ 2020 418
56
+ 2030 447
57
+ 2040 483
58
+ 2050 522
59
+ 2060 563
60
+ 2070 601
61
+ 2080 639
62
+ 2090 674
63
+ 2100 703
aquacrop/data/__init__.py ADDED
@@ -0,0 +1 @@
 
 
1
+ #none
aquacrop/data/brussels_climate.txt ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/brussels_future.txt ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/cambridge_climate.txt ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/champion_climate.txt ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/cmip6_woolpit/CanESM5/CanESM5_historical_1995_2014_52.22057_0.8847.csv ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/cmip6_woolpit/CanESM5/CanESM5_ssp245_2020_2039_52.22057_0.8847.csv ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/cmip6_woolpit/CanESM5/CanESM5_ssp245_2040_2059_52.22057_0.8847.csv ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/cmip6_woolpit/CanESM5/CanESM5_ssp245_2060_2079_52.22057_0.8847.csv ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/cmip6_woolpit/CanESM5/CanESM5_ssp245_2080_2099_52.22057_0.8847.csv ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/cmip6_woolpit/CanESM5/CanESM5_ssp585_2020_2039_52.22057_0.8847.csv ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/cmip6_woolpit/CanESM5/CanESM5_ssp585_2040_2059_52.22057_0.8847.csv ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/cmip6_woolpit/CanESM5/CanESM5_ssp585_2060_2079_52.22057_0.8847.csv ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/cmip6_woolpit/CanESM5/CanESM5_ssp585_2080_2099_52.22057_0.8847.csv ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/cmip6_woolpit/MIROC6/MIROC6_historical_1995_2014_52.221142_0.884217.csv ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/cmip6_woolpit/MIROC6/MIROC6_ssp245_2020_2039_52.221142_0.884217.csv ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/cmip6_woolpit/MIROC6/MIROC6_ssp245_2040_2059_52.221142_0.884217.csv ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/cmip6_woolpit/MIROC6/MIROC6_ssp245_2060_2079_52.221142_0.884217.csv ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/cmip6_woolpit/MIROC6/MIROC6_ssp245_2080_2099_52.221142_0.884217.csv ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/cmip6_woolpit/MIROC6/MIROC6_ssp585_2020_2039_52.221142_0.884217.csv ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/cmip6_woolpit/MIROC6/MIROC6_ssp585_2040_2059_52.221142_0.884217.csv ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/cmip6_woolpit/MIROC6/MIROC6_ssp585_2060_2079_52.221142_0.884217.csv ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/cmip6_woolpit/MIROC6/MIROC6_ssp585_2080_2099_52.221142_0.884217.csv ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/cmip6_woolpit/NorESM2-LM/NorESM2-LM_historical_1995_2014_52.220307_0.884914.csv ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/cmip6_woolpit/NorESM2-LM/NorESM2-LM_ssp245_2020_2039_52.220307_0.884914.csv ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/cmip6_woolpit/NorESM2-LM/NorESM2-LM_ssp245_2040_2059_52.220307_0.884914.csv ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/cmip6_woolpit/NorESM2-LM/NorESM2-LM_ssp245_2060_2079_52.220307_0.884914.csv ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/cmip6_woolpit/NorESM2-LM/NorESM2-LM_ssp245_2080_2099_52.220307_0.884914.csv ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/cmip6_woolpit/NorESM2-LM/NorESM2-LM_ssp585_2020_2039_52.220307_0.884914.csv ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/cmip6_woolpit/NorESM2-LM/NorESM2-LM_ssp585_2040_2059_52.220307_0.884914.csv ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/cmip6_woolpit/NorESM2-LM/NorESM2-LM_ssp585_2060_2079_52.220307_0.884914.csv ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/cmip6_woolpit/NorESM2-LM/NorESM2-LM_ssp585_2080_2099_52.220307_0.884914.csv ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/cordoba_climate.txt ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/hyderabad_climate.txt ADDED
The diff for this file is too large to render. See raw diff
 
aquacrop/data/lincolnshire_climate.txt ADDED
The diff for this file is too large to render. See raw diff