pyfao56v2 0.5.6__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.

Potentially problematic release.


This version of pyfao56v2 might be problematic. Click here for more details.

Files changed (43) hide show
  1. pyfao56v2-0.5.6/.gitignore +168 -0
  2. pyfao56v2-0.5.6/LICENSE +21 -0
  3. pyfao56v2-0.5.6/PKG-INFO +66 -0
  4. pyfao56v2-0.5.6/README.md +34 -0
  5. pyfao56v2-0.5.6/pyproject.toml +79 -0
  6. pyfao56v2-0.5.6/src/pyfao56v2/__init__.py +46 -0
  7. pyfao56v2-0.5.6/src/pyfao56v2/autoirrigate.py +248 -0
  8. pyfao56v2-0.5.6/src/pyfao56v2/forecast.py +186 -0
  9. pyfao56v2-0.5.6/src/pyfao56v2/irrigation.py +118 -0
  10. pyfao56v2-0.5.6/src/pyfao56v2/main.py +442 -0
  11. pyfao56v2-0.5.6/src/pyfao56v2/model.py +789 -0
  12. pyfao56v2-0.5.6/src/pyfao56v2/parameters.py +282 -0
  13. pyfao56v2-0.5.6/src/pyfao56v2/refet.py +386 -0
  14. pyfao56v2-0.5.6/src/pyfao56v2/tools/__init__.py +34 -0
  15. pyfao56v2-0.5.6/src/pyfao56v2/tools/euptfv2/FC_EUHYDI/FC_PTF01.rdata +0 -0
  16. pyfao56v2-0.5.6/src/pyfao56v2/tools/euptfv2/FC_EUHYDI/FC_PTF02.rdata +0 -0
  17. pyfao56v2-0.5.6/src/pyfao56v2/tools/euptfv2/FC_EUHYDI/FC_PTF03.rdata +0 -0
  18. pyfao56v2-0.5.6/src/pyfao56v2/tools/euptfv2/FC_EUHYDI/FC_PTF04.rdata +0 -0
  19. pyfao56v2-0.5.6/src/pyfao56v2/tools/euptfv2/FC_EUHYDI/FC_PTF06.rdata +0 -0
  20. pyfao56v2-0.5.6/src/pyfao56v2/tools/euptfv2/FC_EUHYDI/FC_PTF07.rdata +0 -0
  21. pyfao56v2-0.5.6/src/pyfao56v2/tools/euptfv2/FC_EUHYDI/FC_PTF08.rdata +0 -0
  22. pyfao56v2-0.5.6/src/pyfao56v2/tools/euptfv2/FC_EUHYDI/FC_PTF09.rdata +0 -0
  23. pyfao56v2-0.5.6/src/pyfao56v2/tools/euptfv2/FC_EUHYDI/FC_PTF11.rdata +0 -0
  24. pyfao56v2-0.5.6/src/pyfao56v2/tools/euptfv2/FC_EUHYDI/FC_PTF14.rdata +0 -0
  25. pyfao56v2-0.5.6/src/pyfao56v2/tools/euptfv2/WP_EUHYDI/WP_PTF01.rdata +0 -0
  26. pyfao56v2-0.5.6/src/pyfao56v2/tools/euptfv2/WP_EUHYDI/WP_PTF02.rdata +0 -0
  27. pyfao56v2-0.5.6/src/pyfao56v2/tools/euptfv2/WP_EUHYDI/WP_PTF05.rdata +0 -0
  28. pyfao56v2-0.5.6/src/pyfao56v2/tools/euptfv2/WP_EUHYDI/WP_PTF07.rdata +0 -0
  29. pyfao56v2-0.5.6/src/pyfao56v2/tools/euptfv2/WP_EUHYDI/WP_PTF08.rdata +0 -0
  30. pyfao56v2-0.5.6/src/pyfao56v2/tools/euptfv2/WP_EUHYDI/WP_PTF09.rdata +0 -0
  31. pyfao56v2-0.5.6/src/pyfao56v2/tools/euptfv2/WP_EUHYDI/WP_PTF17.rdata +0 -0
  32. pyfao56v2-0.5.6/src/pyfao56v2/tools/euptfv2/list_of_final_PTFs.csv +33 -0
  33. pyfao56v2-0.5.6/src/pyfao56v2/tools/euptfv2.py +136 -0
  34. pyfao56v2-0.5.6/src/pyfao56v2/tools/lut.py +14 -0
  35. pyfao56v2-0.5.6/src/pyfao56v2/tools/luts/crop.csv +10 -0
  36. pyfao56v2-0.5.6/src/pyfao56v2/tools/luts/irrigation.csv +8 -0
  37. pyfao56v2-0.5.6/src/pyfao56v2/tools/luts/soil.csv +10 -0
  38. pyfao56v2-0.5.6/src/pyfao56v2/tools/misc.py +76 -0
  39. pyfao56v2-0.5.6/src/pyfao56v2/tools/pheno.py +91 -0
  40. pyfao56v2-0.5.6/src/pyfao56v2/tools/rosetta.py +97 -0
  41. pyfao56v2-0.5.6/src/pyfao56v2/tools/van_genuchten.py +23 -0
  42. pyfao56v2-0.5.6/src/pyfao56v2/tools/visualization.py +452 -0
  43. pyfao56v2-0.5.6/src/pyfao56v2/weather.py +204 -0
@@ -0,0 +1,168 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py,cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ #Pipfile.lock
96
+
97
+ # poetry
98
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
102
+ #poetry.lock
103
+
104
+ # pdm
105
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
106
+ #pdm.lock
107
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
108
+ # in version control.
109
+ # https://pdm.fming.dev/latest/usage/project/#working-with-version-control
110
+ .pdm.toml
111
+ .pdm-python
112
+ .pdm-build/
113
+
114
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
115
+ __pypackages__/
116
+
117
+ # Celery stuff
118
+ celerybeat-schedule
119
+ celerybeat.pid
120
+
121
+ # SageMath parsed files
122
+ *.sage.py
123
+
124
+ # Environments
125
+ .env
126
+ .venv
127
+ env/
128
+ venv/
129
+ ENV/
130
+ env.bak/
131
+ venv.bak/
132
+
133
+ # Spyder project settings
134
+ .spyderproject
135
+ .spyproject
136
+
137
+ # Rope project settings
138
+ .ropeproject
139
+
140
+ # mkdocs documentation
141
+ /site
142
+
143
+ # mypy
144
+ .mypy_cache/
145
+ .dmypy.json
146
+ dmypy.json
147
+
148
+ # Pyre type checker
149
+ .pyre/
150
+
151
+ # pytype static type analyzer
152
+ .pytype/
153
+
154
+ # Cython debug symbols
155
+ cython_debug/
156
+
157
+ # PyCharm
158
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
159
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
160
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
161
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
162
+ #.idea/
163
+
164
+ TODO/
165
+ .history/
166
+ playground.ipynb
167
+ service_secrets.json
168
+ .cache.sqlite
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 AI, Data & Space
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,66 @@
1
+ Metadata-Version: 2.4
2
+ Name: pyfao56v2
3
+ Version: 0.5.6
4
+ Summary: Enhanced pyFAO56 library
5
+ Project-URL: Repository, https://github.com/links-ads/guardians-pyfao56
6
+ Project-URL: issues, https://github.com/links-ads/guardians-pyfao56/issues
7
+ Author-email: Tommaso Monopoli <tommaso.monopoli@linksfoundation.com>
8
+ License-File: LICENSE
9
+ Keywords: agriculture,crop,evapotranspiration,fao56,irrigation,pyfao56,water
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Natural Language :: English
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Topic :: Scientific/Engineering :: Hydrology
15
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
+ Requires-Python: ~=3.10.0
17
+ Requires-Dist: lxml>=5.3.0
18
+ Requires-Dist: matplotlib>=3.9.2
19
+ Requires-Dist: numpy>=1.26.4
20
+ Requires-Dist: openmeteo-requests>=1.3.0
21
+ Requires-Dist: openpyxl>=3.1.5
22
+ Requires-Dist: pandas>=2.2.3
23
+ Requires-Dist: pyyaml>=6.0.2
24
+ Requires-Dist: requests-cache>=1.2.1
25
+ Requires-Dist: requests>=2.32.3
26
+ Requires-Dist: retry-requests>=2.0.0
27
+ Requires-Dist: rosetta-soil>=0.1.2
28
+ Requires-Dist: urllib3>=2.2.3
29
+ Provides-Extra: r
30
+ Requires-Dist: rpy2==3.5.1; extra == 'r'
31
+ Description-Content-Type: text/markdown
32
+
33
+ # pyfao56 v2
34
+ Enhanced pyFAO56 library
35
+
36
+ ## Installation
37
+
38
+ ```bash
39
+ pip install --extra-index-url https://test.pypi.org/simple/ pyfao56v2
40
+ ```
41
+
42
+ ## Usage
43
+
44
+ `pyfao56v2` can be used to run a water balance simulation given a set of input parameters:
45
+ - soil parameters
46
+ - crop parameters
47
+ - historical weather data
48
+ - irrigation data (optional)
49
+ - autoirrigation rule(s) (optional)
50
+
51
+ See the [example.ipynb](https://github.com/links-ads/guardians-pyfao56/blob/main/docs/example.ipynb) notebook for a detailed example.
52
+
53
+ ## Contributing
54
+
55
+ Interested in contributing? Check out the contributing guidelines. Please note that this project is released with a Code of Conduct. By contributing to this project, you agree to abide by its terms.
56
+
57
+ ## License
58
+
59
+ `pyfao56v2` was created by Tommaso Monopoli. It is licensed under the terms of the MIT license.
60
+ This package is based on the [`pyfao56`](https://github.com/kthorp/pyfao56) library, developed by USDA-ARS and licensed under the terms of the [CC0 1.0 Universal](https://creativecommons.org/publicdomain/zero/1.0/) (no copyright).
61
+ This project is not affiliated with or endorsed by the USDA-ARS.
62
+
63
+ ## Credits
64
+
65
+ This work builds upon the [`pyfao56`](https://github.com/kthorp/pyfao56) library, developed by USDA-ARS.
66
+ The CI-CD workflow is based on the [py-pkgs.org](https://py-pkgs.org/) guide.
@@ -0,0 +1,34 @@
1
+ # pyfao56 v2
2
+ Enhanced pyFAO56 library
3
+
4
+ ## Installation
5
+
6
+ ```bash
7
+ pip install --extra-index-url https://test.pypi.org/simple/ pyfao56v2
8
+ ```
9
+
10
+ ## Usage
11
+
12
+ `pyfao56v2` can be used to run a water balance simulation given a set of input parameters:
13
+ - soil parameters
14
+ - crop parameters
15
+ - historical weather data
16
+ - irrigation data (optional)
17
+ - autoirrigation rule(s) (optional)
18
+
19
+ See the [example.ipynb](https://github.com/links-ads/guardians-pyfao56/blob/main/docs/example.ipynb) notebook for a detailed example.
20
+
21
+ ## Contributing
22
+
23
+ Interested in contributing? Check out the contributing guidelines. Please note that this project is released with a Code of Conduct. By contributing to this project, you agree to abide by its terms.
24
+
25
+ ## License
26
+
27
+ `pyfao56v2` was created by Tommaso Monopoli. It is licensed under the terms of the MIT license.
28
+ This package is based on the [`pyfao56`](https://github.com/kthorp/pyfao56) library, developed by USDA-ARS and licensed under the terms of the [CC0 1.0 Universal](https://creativecommons.org/publicdomain/zero/1.0/) (no copyright).
29
+ This project is not affiliated with or endorsed by the USDA-ARS.
30
+
31
+ ## Credits
32
+
33
+ This work builds upon the [`pyfao56`](https://github.com/kthorp/pyfao56) library, developed by USDA-ARS.
34
+ The CI-CD workflow is based on the [py-pkgs.org](https://py-pkgs.org/) guide.
@@ -0,0 +1,79 @@
1
+ [project]
2
+ name = "pyfao56v2"
3
+ version = "0.5.6"
4
+ description = "Enhanced pyFAO56 library"
5
+ authors = [{ name = "Tommaso Monopoli", email = "tommaso.monopoli@linksfoundation.com" }]
6
+ requires-python = "~=3.10.0"
7
+ readme = "README.md"
8
+ license-files = ["LICENSE"]
9
+ keywords = [
10
+ "fao56",
11
+ "pyfao56",
12
+ "evapotranspiration",
13
+ "crop",
14
+ "irrigation",
15
+ "water",
16
+ "agriculture",
17
+ ]
18
+ classifiers = [
19
+ "Programming Language :: Python :: 3",
20
+ "License :: OSI Approved :: MIT License",
21
+ "Operating System :: OS Independent",
22
+ "Natural Language :: English",
23
+ "Topic :: Scientific/Engineering :: Hydrology",
24
+ "Topic :: Software Development :: Libraries :: Python Modules",
25
+ ]
26
+ dependencies = [
27
+ "lxml>=5.3.0",
28
+ "matplotlib>=3.9.2",
29
+ "numpy>=1.26.4",
30
+ "openpyxl>=3.1.5",
31
+ "pandas>=2.2.3",
32
+ "pyyaml>=6.0.2",
33
+ "requests>=2.32.3",
34
+ "urllib3>=2.2.3",
35
+ "rosetta-soil>=0.1.2",
36
+ "openmeteo-requests>=1.3.0",
37
+ "requests-cache>=1.2.1",
38
+ "retry-requests>=2.0.0",
39
+ ]
40
+
41
+ [project.optional-dependencies]
42
+ r = [
43
+ "rpy2==3.5.1"
44
+ ]
45
+
46
+ [project.urls]
47
+ Repository = "https://github.com/links-ads/guardians-pyfao56"
48
+ issues = "https://github.com/links-ads/guardians-pyfao56/issues"
49
+
50
+ [dependency-groups]
51
+ dev = [
52
+ "ipykernel>=6.29.5",
53
+ "pytest>=8.3.3,<9",
54
+ "jupyter>=1.1.1,<2",
55
+ "myst-nb>=1.1.2,<2 ; python_version ~= '3.9'",
56
+ "sphinx-autoapi>=3.3.3,<4",
57
+ "sphinx-rtd-theme>=3.0.1,<4",
58
+ "python-semantic-release>=10.0.0",
59
+ ]
60
+
61
+ [tool.hatch.build.targets.sdist]
62
+ include = ["src/pyfao56v2"]
63
+ exclude = ["src/TODO"]
64
+
65
+ [tool.hatch.build.targets.wheel]
66
+ include = ["src/pyfao56v2"]
67
+ exclude = ["src/TODO"]
68
+
69
+ [tool.hatch.build.targets.wheel.sources]
70
+ "src/pyfao56v2" = "pyfao56v2"
71
+
72
+ [build-system]
73
+ requires = ["hatchling"]
74
+ build-backend = "hatchling.build"
75
+
76
+ [tool.semantic_release]
77
+ version_source = "pyproject.toml:project.version" # version location
78
+ branch = "main" # branch to make releases of
79
+ changelog_file = "CHANGELOG.md" # changelog file
@@ -0,0 +1,46 @@
1
+ """
2
+ ########################################################################
3
+ The pyfao56v2 Python package builds on top of the pyfao56 library mantained by USDA-ARS.
4
+
5
+ - pyfao56 facilitates FAO-56 computations of daily soil
6
+ water balance using the dual crop coefficient method to estimate crop
7
+ evapotranspiration (ET).
8
+ The FAO-56 method is described in the following documentation:
9
+ Allen, R. G., Pereira, L. S., Raes, D., Smith, M., 1998. FAO Irrigation
10
+ and Drainage Paper No. 56. Crop Evapotranspiration: Guidelines for
11
+ Computing Crop Water Requirements. Food and Agriculture Organization of
12
+ the United Nations, Rome Italy.
13
+ http://www.fao.org/3/x0490e/x0490e00.htm
14
+ Reference ET is computed using the ASCE Standardized Reference ET
15
+ Equation, which is described in the following documentation:
16
+ ASCE Task Committee on Standardization of Reference Evapotranspiration
17
+ (Walter, I. A., Allen, R. G., Elliott, R., Itenfisu, D., Brown, P.,
18
+ Jensen, M. E.,Mecham, B., Howell, T. A., Snyder, R., Eching, S.,
19
+ Spofford, T., Hattendorf, M., Martin, D., Cuenca, R. H., Wright, J. L.)
20
+ , 2005. The ASCE Standardized Reference Evapotranspiration Equation.
21
+ American Society of Civil Engineers, Reston, VA.
22
+ https://ascelibrary.org/doi/book/10.1061/9780784408056
23
+
24
+ - pyfao56v2 extends the pyfao56 library by:
25
+ - working with "full" dates (YYYY-MM-DD) instead of day-of-year dates
26
+ (YYYY-DOY)
27
+ - allowing the input of custom Kcb time series, letting go of the
28
+ trapezoidal Kcb curve in the original FAO-56 method
29
+ - introducing lookup tables for crop, soil, and irrigation parameters
30
+ - other improvements yet to be documented...
31
+ ########################################################################
32
+ """
33
+
34
+ # pyfao56v2/
35
+ from .main import simulate, WaterBalance
36
+ from .model import Model
37
+ from .parameters import Parameters
38
+ from .weather import Weather
39
+ from .irrigation import Irrigation
40
+ from .autoirrigate import AutoIrrigate
41
+ from .forecast import Forecast
42
+ #from .soil_profile import SoilProfile
43
+ #from .update import Update
44
+
45
+ # pyfao56v2/tools/
46
+ from .tools import Visualization
@@ -0,0 +1,248 @@
1
+ """
2
+ ########################################################################
3
+ The autoirrigate.py module contains the AutoIrrigate class, which
4
+ provides I/O tools for defining conditions for scheduling irrigation
5
+ automatically in pyfao56.
6
+ ########################################################################
7
+ """
8
+
9
+ import pandas as pd
10
+
11
+ class AutoIrrigate:
12
+ """A class for managing multiple sets of autoirrigation conditions
13
+
14
+ Attributes
15
+ ----------
16
+ data : DataFrame
17
+ AutoIrrigate data with mixed data types
18
+ * index - counter as int
19
+ * columns - ['start','end','alre','idow','fpdep','fpday','fpact',
20
+ 'mad','madDr','ksc','dsli','dsle','evnt','icon',
21
+ 'itdr','itfdr','ietrd','ietri','ietre','ettyp',
22
+ 'iper','ieff','imin','imax','fw']
23
+
24
+ Variables to determine if autoirrigation occurs or not:
25
+ * * start - Autoirrigate only on start date or later
26
+ (str, 'yyyy-ddd')
27
+ * * end - Autoirrigate only on end date or earlier
28
+ (str, 'yyyy-ddd')
29
+ * * alre - Autoirrigate only after last reported irrigation
30
+ event (boolean)
31
+ * * idow - Autoirrigate only on specified days of the week
32
+ (str, e.g. '0123456'; default is all days)
33
+ 0=sun, 1=mon, 2=tue, 3=wed, 4=thu, 5=fri, 6=sat
34
+ * * fpdep - Threshold for cumulative forecasted precipitation depth
35
+ (float, mm; default: 10.)
36
+ * * fpday : Number of days to consider for computing the cumulative
37
+ forecasted precipitation depth
38
+ (int, days; default: 1)
39
+ * * fpact : Action if forecasted precip is above threshold:
40
+ None (default) - Proceed to autoirrigate anyway if needed
41
+ 'cancel' - Do not autoirrigate
42
+ 'reduce' - Deduct forecasted precip from autoirrigation amount
43
+ * * mad - Management allowed depletion (float, mm/mm)
44
+ Autoirrigate if fractional root-zone soil water
45
+ depletion (fDr) >= mad
46
+ * * madDr - Management allowed depletion (float, mm)
47
+ Autoirrigate if root-zone soil water depletion (Dr) >= madDr
48
+ * * ksc - Critical value for transpiration reduction factor Ks
49
+ (float, 0-1, 1:full transpiration, 0:no trans.)
50
+ Autoirrigate if Ks <= ksc
51
+ * * dsli - Days since last irrigation event
52
+ (float, days)
53
+ Autoirrigate if days since last irrigation >= dsli
54
+ * * dsle - Days since last watering event, considering both
55
+ eff. precip and eff. irrigation (float, days)
56
+ Autoirrigate if days since last watering event >= dsle
57
+ * * evnt - Minimum depth of effective precipitation and
58
+ effective irrigation to be considered a watering
59
+ event (float, mm)
60
+
61
+ The default autoirrigation amount is root-zone soil water depletion (Dr,
62
+ mm). Variables to alter this irrigation amount are as follows:
63
+ * * icon - Apply a constant autoirrigation amount (float, mm)
64
+ * * itdr - Target a specfic root-zone soil water depletion (Dr)
65
+ following autoirrigation (float, mm)
66
+ * * itfdr - Target a specific fractional root-zone soil water
67
+ depletion following autoirrigation (float, mm/mm)
68
+ * * ietrd - Replace ET minus effective precipitation from the
69
+ past given number of days (int, days)
70
+ * * ietri - Replace ET minus effective precipitation since the
71
+ last irrigation event (boolean)
72
+ * * ietre - Replace ET minus effective precipitation since the
73
+ last watering event (boolean)
74
+ * * ettyp - Specify type of ET to adjust, when one among ietrd, ietri or ietre is specified
75
+ 'ETcadj' (default) - Replace ETcadj less precip
76
+ 'ETc' - Replace ETc less precip
77
+ * * iper - Adjust the autoirrigation amount by a fixed
78
+ percentage (float, %)
79
+ * * ieff - Consider an application efficiency for
80
+ autoirrigation (float, %; default: same as
81
+ irrigation efficiency)
82
+ * * imin - Limit autoirrigation to >= minimum amount (float,mm)
83
+ * * imax - Limit autoirrigation to <= maximum amount (float,mm)
84
+ * * fw - Fraction of soil surface wetted (FAO-56 Table 20; default: 1.0)
85
+ """
86
+
87
+ COLS = ['start','end','alre','idow','fpdep','fpday',
88
+ 'fpact','mad','madDr','ksc','dsli','dsle','evnt',
89
+ 'icon','itdr','itfdr','ietrd','ietri','ietre',
90
+ 'ettyp','iper','ieff','imin','imax','fw']
91
+
92
+ def __init__(self, data=None, **kwargs):
93
+ """Initialize the AutoIrrigate class attributes.
94
+
95
+ Parameters
96
+ ----------
97
+ data : DataFrame, optional
98
+ AutoIrrigation rules
99
+ columns - ['start','end','alre','idow','fpdep','fpday',
100
+ 'fpact','mad','madDr','ksc','dsli','dsle','evnt',
101
+ 'icon','itdr','itfdr','ietrd','ietri','ietre',
102
+ 'ettyp','iper','ieff','imin','imax','fw']
103
+ """
104
+
105
+ self.data = pd.DataFrame(columns=self.COLS)
106
+
107
+ if data is not None:
108
+ assert set(data.columns).issubset(set(self.COLS)), 'Invalid column names are present'
109
+ # add missing columns with NaN values
110
+ self.data = pd.concat([self.data, data])
111
+
112
+ # cast start and end columns to datetime
113
+ self.data['start'] = pd.to_datetime(self.data['start'])
114
+ self.data['end'] = pd.to_datetime(self.data['end'])
115
+
116
+
117
+ def add_rule(self, start, end, alre=True, idow='0123456', fpdep=10.,
118
+ fpday=1, fpact=None, mad=float('NaN'),
119
+ madDr=float('NaN'), ksc=float('NaN'), dsli=float('NaN'),
120
+ dsle=float('NaN'), evnt=10., icon=None,
121
+ itdr=None, itfdr=None, ietrd=None,
122
+ ietri=False, ietre=False, ettyp='ETcadj', iper=None,
123
+ ieff=None, imin=None, imax=None, fw=1.0):
124
+ """Add an autoirrigation rule for the given date range"""
125
+
126
+ # check that no other rule is already present for the given date range
127
+ if not self.data.empty:
128
+ assert not ((self.data['start'] <= pd.to_datetime(end)) &
129
+ (self.data['end'] >= pd.to_datetime(start))).any(), \
130
+ f'Rule already exists for the given date range: {start} to {end}'
131
+ # check that the start and end dates are valid
132
+ assert isinstance(start, str), f'start must be a string. Got type {type(start)}'
133
+ assert isinstance(end, str), f'end must be a string. Got type {type(end)}'
134
+ assert pd.to_datetime(start, format='%Y-%m-%d', errors='coerce') is not pd.NaT, \
135
+ f'start must be a valid date string in the format yyyy-mm-dd. Got {start}'
136
+ assert pd.to_datetime(end, format='%Y-%m-%d', errors='coerce') is not pd.NaT, \
137
+ f'end must be a valid date string in the format yyyy-mm-dd. Got {end}'
138
+ assert pd.to_datetime(start) <= pd.to_datetime(end), \
139
+ f'start date must be before end date. Got {start} and {end}'
140
+ # various checks on given arguments
141
+ assert isinstance(alre, bool), f'alre must be a boolean. Got type {type(alre)}'
142
+ assert isinstance(idow, str), f'idow must be a string. Got type {type(idow)}'
143
+ assert len(idow) <= 7, f'idow must be a string of at most 7 numbers. Got {idow}'
144
+ assert all(c in '0123456' for c in idow), \
145
+ f'idow must be a string containing numbers in 0,...,6. Got {idow}'
146
+ assert fpact is None or fpact in ['cancel', 'reduce'], \
147
+ f'Invalid value for fpact. Must be None, "cancel", or "reduce". Got {fpact}'
148
+ assert isinstance(fpday, int), f'fpday must be an integer. Got type {type(fpday)}'
149
+ assert fpday >= 0, f'fpday must be >= 0. Got {fpday}'
150
+ assert fpdep >= 0, f'fpdep must be >= 0. Got {fpdep}'
151
+ if ieff is not None:
152
+ assert isinstance(ieff, (int, float)), \
153
+ f'ieff must be an integer or float. Got type {type(ieff)}'
154
+ assert 0 <= ieff <= 100, f'ieff must be between 0 and 100. Got {ieff}'
155
+ f'ieff must be between 0 and 100. Got {ieff}'
156
+ if imin is not None:
157
+ assert isinstance(imin, (int, float)), \
158
+ f'imin must be an integer or float. Got type {type(imin)}'
159
+ assert imin >= 0, f'imin must be >= 0. Got {imin}'
160
+ if imax is not None:
161
+ assert isinstance(imax, (int, float)), \
162
+ f'imax must be an integer or float. Got type {type(imax)}'
163
+ assert imax >= 0, f'imax must be >= 0. Got {imax}'
164
+ if imin is not None and imax is not None:
165
+ assert imin <= imax, f'imax must be >= imin. Got {imin} and {imax}'
166
+ if fw is not None:
167
+ assert isinstance(fw, (int, float)), \
168
+ f'fw must be an integer or float. Got type {type(fw)}'
169
+ assert 0 <= fw <= 1, f'fw must be between 0 and 1. Got {fw}'
170
+ if ietrd is not None:
171
+ assert isinstance(ietrd, int), \
172
+ f'ietrd must be an integer. Got type {type(ietrd)}'
173
+ assert ietrd >= 0, f'ietrd must be >= 0. Got {ietrd}'
174
+ assert sum([
175
+ (icon is not None), (itdr is not None), (itfdr is not None),
176
+ (ietrd is not None), (ietri is True), (ietre is True)
177
+ ]) == 1, \
178
+ 'Exactly one among icon, itdr, itfdr, ietrd, ietri or ietre must be specified'
179
+ assert ettyp in ['ETcadj', 'ETc'], \
180
+ f'Invalid value for ettyp. Must be "ETcadj" or "ETc". Got {ettyp}'
181
+
182
+
183
+
184
+ rule = dict(
185
+ start=pd.to_datetime(start, format='%Y-%m-%d'),
186
+ end=pd.to_datetime(end, format='%Y-%m-%d'),
187
+ alre=alre, idow=idow, fpdep=fpdep,
188
+ fpday=fpday, fpact=fpact, mad=mad, madDr=madDr, ksc=ksc,
189
+ dsli=dsli, dsle=dsle, evnt=evnt, icon=icon, itdr=itdr,
190
+ itfdr=itfdr, ietrd=ietrd, ietri=ietri, ietre=ietre,
191
+ ettyp=ettyp, iper=iper, ieff=ieff, imin=imin, imax=imax,
192
+ fw=fw,
193
+ )
194
+
195
+ self.data = pd.concat([self.data, pd.DataFrame([rule])])
196
+
197
+
198
+ def to_csv(self, path='pyfao56.airr'):
199
+ """Save autoirrigation data to csv file
200
+
201
+ Parameters
202
+ ----------
203
+ path : str
204
+ Filepath for saving the autoirrigation data
205
+ """
206
+
207
+ self.data.to_csv(path, index=False)
208
+
209
+ @classmethod
210
+ def from_csv(cls, path):
211
+ """Load autoirrigation data from csv file
212
+
213
+ Parameters
214
+ ----------
215
+ path : str
216
+ Filepath for loading the autoirrigation data
217
+
218
+ Returns
219
+ -------
220
+ AutoIrrigate
221
+ AutoIrrigate class object
222
+ """
223
+
224
+ data = pd.read_csv(path)
225
+ return cls(data)
226
+
227
+ @classmethod
228
+ def from_rules(cls, rules):
229
+ """Load autoirrigation data from a list of rules
230
+
231
+ Parameters
232
+ ----------
233
+ rules : list
234
+ List of dictionaries containing autoirrigation rules, e.g.:
235
+ [{'start': '2020-01-01', 'end': '2020-12-31', 'alre': True, ...}, ...]
236
+
237
+ Returns
238
+ -------
239
+ AutoIrrigate
240
+ AutoIrrigate class object
241
+ """
242
+
243
+ #data = pd.DataFrame(rules)
244
+ #return cls(data)
245
+ airr = cls()
246
+ for rule in rules:
247
+ airr.add_rule(**rule)
248
+ return airr