pyholos 0.0.1__py3-none-any.whl
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 pyholos might be problematic. Click here for more details.
- pyholos/__init__.py +0 -0
- pyholos/common.py +141 -0
- pyholos/common2.py +157 -0
- pyholos/components/__init__.py +0 -0
- pyholos/components/animals/__init__.py +0 -0
- pyholos/components/animals/beef.py +766 -0
- pyholos/components/animals/common.py +2301 -0
- pyholos/components/animals/dairy.py +341 -0
- pyholos/components/animals/sheep.py +412 -0
- pyholos/components/common.py +170 -0
- pyholos/components/land_management/__init__.py +0 -0
- pyholos/components/land_management/carbon/__init__.py +0 -0
- pyholos/components/land_management/carbon/climate.py +863 -0
- pyholos/components/land_management/carbon/management.py +21 -0
- pyholos/components/land_management/carbon/relative_biomass_information.py +410 -0
- pyholos/components/land_management/carbon/tillage.py +88 -0
- pyholos/components/land_management/common.py +220 -0
- pyholos/components/land_management/crop.py +1233 -0
- pyholos/components/land_management/field_system.py +458 -0
- pyholos/components/land_management/utils.py +66 -0
- pyholos/config.py +49 -0
- pyholos/core_constants.py +20 -0
- pyholos/defaults.py +116 -0
- pyholos/farm/__init__.py +0 -0
- pyholos/farm/enums.py +54 -0
- pyholos/farm/farm.py +101 -0
- pyholos/farm/farm_inputs.py +633 -0
- pyholos/farm/farm_settings.py +542 -0
- pyholos/launching.py +86 -0
- pyholos/postprocessing/__init__.py +0 -0
- pyholos/postprocessing/plots.py +164 -0
- pyholos/postprocessing/postprocessing.py +38 -0
- pyholos/resources/holos/Table_16_Livestock_Coefficients_BeefAndDairy_Cattle_Provider.csv +21 -0
- pyholos/resources/holos/Table_21_Average_Milk_Production_For_Dairy_Cows_By_Province.csv +23 -0
- pyholos/resources/holos/Table_22_Livestock_Coefficients_For_Sheep.csv +28 -0
- pyholos/resources/holos/Table_29_Percentage_Total_Manure_Produced_In_Systems.csv +56 -0
- pyholos/resources/holos/Table_30_Default_Bedding_Material_Composition_Provider.csv +28 -0
- pyholos/resources/holos/Table_50_Fuel_Energy_Requirement_Estimates_By_Region.csv +81 -0
- pyholos/resources/holos/Table_51_Herbicide_Energy_Requirement_Estimates_By_Region.csv +81 -0
- pyholos/resources/holos/Table_61_Fractions_of_dairy_cattle_N_volatilized.csv +25 -0
- pyholos/resources/holos/Table_62_Fractions_of_swine_N_volatilized.csv +25 -0
- pyholos/resources/holos/Table_6_Manure_Types_And_Default_Composition.csv +126 -0
- pyholos/resources/holos/Table_7_Relative_Biomass_Information.csv +112 -0
- pyholos/resources/holos/Table_9_Default_Values_For_Nitrogen_Lignin_In_Crops.csv +72 -0
- pyholos/resources/holos/Table_Tillage_Factor.csv +13 -0
- pyholos/resources/holos/feeds.csv +223 -0
- pyholos/resources/holos/main_tables.py +493 -0
- pyholos/resources/holos/small_area_yields.csv +167159 -0
- pyholos/resources/soil_landscapes_of_canada_v3r2.zip +0 -0
- pyholos/soil.py +439 -0
- pyholos/utils.py +83 -0
- pyholos-0.0.1.dist-info/METADATA +16 -0
- pyholos-0.0.1.dist-info/RECORD +55 -0
- pyholos-0.0.1.dist-info/WHEEL +4 -0
- pyholos-0.0.1.dist-info/licenses/LICENSE +677 -0
|
@@ -0,0 +1,542 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
from typing import Any
|
|
3
|
+
|
|
4
|
+
from pyholos.common import HolosVar
|
|
5
|
+
from pyholos.core_constants import CoreConstants
|
|
6
|
+
from pyholos.defaults import Defaults
|
|
7
|
+
from pyholos.farm.enums import (CarbonModellingStrategies,
|
|
8
|
+
ChosenClimateAcquisition,
|
|
9
|
+
YieldAssignmentMethod)
|
|
10
|
+
from pyholos.soil import set_soil_properties
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class FarmSettingsVar(HolosVar):
|
|
14
|
+
def __init__(
|
|
15
|
+
self,
|
|
16
|
+
name: str,
|
|
17
|
+
value: Any
|
|
18
|
+
):
|
|
19
|
+
super().__init__(
|
|
20
|
+
name=name,
|
|
21
|
+
value=value)
|
|
22
|
+
|
|
23
|
+
def to_text(self):
|
|
24
|
+
return f'{self.name} = {self.value}'
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class ParamGeneric:
|
|
28
|
+
def __init__(self, title: str):
|
|
29
|
+
self.title = f'# {title}'
|
|
30
|
+
|
|
31
|
+
def to_list(self) -> list[str]:
|
|
32
|
+
return [self.title] + [getattr(self, v).to_text() for v in self.__dict__ if
|
|
33
|
+
(not v.startswith(('title', '_', '__')) and not callable(v))]
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class ParamsGeneral(ParamGeneric):
|
|
37
|
+
def __init__(
|
|
38
|
+
self,
|
|
39
|
+
polygon_id: int,
|
|
40
|
+
latitude: float,
|
|
41
|
+
longitude: float,
|
|
42
|
+
carbon_concentration: float = 0.45,
|
|
43
|
+
emergence_day: int = 141,
|
|
44
|
+
ripening_day: int = 197,
|
|
45
|
+
variance: float | float = 300,
|
|
46
|
+
alfa: float = 0.7,
|
|
47
|
+
decomposition_minimum_temperature: float = -3.78,
|
|
48
|
+
decomposition_maximum_temperature: float = 30,
|
|
49
|
+
moisture_response_function_at_saturation: float = 0.42,
|
|
50
|
+
moisture_response_function_at_wilting_point: float = 0.18,
|
|
51
|
+
**kwargs
|
|
52
|
+
):
|
|
53
|
+
super().__init__(title="General")
|
|
54
|
+
|
|
55
|
+
self.yield_assignment_method = FarmSettingsVar(
|
|
56
|
+
name="Yield Assignment Method", value=YieldAssignmentMethod.SmallAreaData.name)
|
|
57
|
+
self.polygon_number = FarmSettingsVar(name="Polygon Number", value=polygon_id)
|
|
58
|
+
self.latitude = FarmSettingsVar(name="Latitude", value=latitude)
|
|
59
|
+
self.Longitude = FarmSettingsVar(name="Longitude", value=longitude)
|
|
60
|
+
self.carbon_concentration = FarmSettingsVar(name="Carbon Concentration (kg kg^-1)", value=carbon_concentration)
|
|
61
|
+
self.emergence_day = FarmSettingsVar(name="Emergence Day", value=emergence_day)
|
|
62
|
+
self.ripening_day = FarmSettingsVar(name="Ripening Day", value=ripening_day)
|
|
63
|
+
self.variance = FarmSettingsVar(name="Variance", value=variance)
|
|
64
|
+
self.alfa = FarmSettingsVar(name="Alfa", value=alfa)
|
|
65
|
+
self.decomposition_minimum_temperature = FarmSettingsVar(
|
|
66
|
+
name="Decomposition Minimum Temperature (°C)", value=decomposition_minimum_temperature)
|
|
67
|
+
self.decomposition_maximum_temperature = FarmSettingsVar(
|
|
68
|
+
name="Decomposition Maximum Temperature (°C) ", value=decomposition_maximum_temperature)
|
|
69
|
+
self.moisture_response_function_at_saturation = FarmSettingsVar(
|
|
70
|
+
name="Moisture Response Function At Saturation", value=moisture_response_function_at_saturation)
|
|
71
|
+
self.moisture_response_function_at_wilting_point = FarmSettingsVar(
|
|
72
|
+
name="Moisture Response Function At Wilting Point", value=moisture_response_function_at_wilting_point)
|
|
73
|
+
|
|
74
|
+
pass
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
class ParamsAnnualCrops(ParamGeneric):
|
|
78
|
+
def __init__(
|
|
79
|
+
self,
|
|
80
|
+
percentage_of_product_returned_to_soil_for_annuals: int | float = 2,
|
|
81
|
+
percentage_of_straw_returned_to_soil_for_annuals: int | float = 100,
|
|
82
|
+
percentage_of_roots_returned_to_soil_for_annuals: int | float = 100,
|
|
83
|
+
**kwargs
|
|
84
|
+
):
|
|
85
|
+
super().__init__(title="Annual Crops")
|
|
86
|
+
|
|
87
|
+
self.percentage_of_product_returned_to_soil_for_annuals = FarmSettingsVar(
|
|
88
|
+
name="Percentage Of Product Returned To Soil For Annuals",
|
|
89
|
+
value=percentage_of_product_returned_to_soil_for_annuals)
|
|
90
|
+
self.percentage_of_straw_returned_to_soil_for_annuals = FarmSettingsVar(
|
|
91
|
+
name="Percentage Of Straw Returned To Soil For Annuals",
|
|
92
|
+
value=percentage_of_straw_returned_to_soil_for_annuals)
|
|
93
|
+
self.percentage_of_roots_returned_to_soil_for_annuals = FarmSettingsVar(
|
|
94
|
+
name="Percentage Of Roots Returned To Soil For Annuals",
|
|
95
|
+
value=percentage_of_roots_returned_to_soil_for_annuals)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class ParamsSilageCrops(ParamGeneric):
|
|
99
|
+
def __init__(
|
|
100
|
+
self,
|
|
101
|
+
percentage_of_product_yield_returned_to_soil_for_silage_crops: int | float = 35,
|
|
102
|
+
percentage_of_roots_returned_to_soil_for_silage_crops: int | float = 100,
|
|
103
|
+
**kwargs
|
|
104
|
+
):
|
|
105
|
+
super().__init__(title="Silage Crops")
|
|
106
|
+
|
|
107
|
+
self.percentage_of_product_yield_returned_to_soil_for_silage_crops = FarmSettingsVar(
|
|
108
|
+
name="Percentage Of Product Yield Returned To Soil For Silage Crops",
|
|
109
|
+
value=percentage_of_product_yield_returned_to_soil_for_silage_crops)
|
|
110
|
+
self.percentage_of_roots_returned_to_soil_for_silage_crops = FarmSettingsVar(
|
|
111
|
+
name="Percentage Of Roots Returned To Soil For Silage Crops",
|
|
112
|
+
value=percentage_of_roots_returned_to_soil_for_silage_crops)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
class ParamsCoverCrops(ParamGeneric):
|
|
116
|
+
def __init__(
|
|
117
|
+
self,
|
|
118
|
+
percentage_of_product_yield_returned_to_soil_for_cover_crops: int | float = 100,
|
|
119
|
+
percentage_of_product_yield_returned_to_soil_for_cover_crops_forage: int | float = 35,
|
|
120
|
+
percentage_of_product_yield_returned_to_soil_for_cover_crops_produce: int | float = 0,
|
|
121
|
+
percentage_of_straw_returned_to_soil_for_cover_crops: int | float = 100,
|
|
122
|
+
percentage_of_roots_returned_to_soil_for_cover_crops: int | float = 100,
|
|
123
|
+
**kwargs
|
|
124
|
+
):
|
|
125
|
+
super().__init__(title="Cover Crops")
|
|
126
|
+
|
|
127
|
+
self.percentage_of_product_yield_returned_to_soil_for_cover_crops = FarmSettingsVar(
|
|
128
|
+
name="Percentage Of Product Yield Returned To Soil For Cover Crops",
|
|
129
|
+
value=percentage_of_product_yield_returned_to_soil_for_cover_crops)
|
|
130
|
+
self.percentage_of_product_yield_returned_to_soil_for_cover_crops_forage = FarmSettingsVar(
|
|
131
|
+
name="Percentage Of Product Yield Returned To Soil For Cover Crops Forage",
|
|
132
|
+
value=percentage_of_product_yield_returned_to_soil_for_cover_crops_forage)
|
|
133
|
+
self.percentage_of_product_yield_returned_to_soil_for_cover_crops_produce = FarmSettingsVar(
|
|
134
|
+
name="Percentage Of Product Yield Returned To Soil For Cover Crops Produce",
|
|
135
|
+
value=percentage_of_product_yield_returned_to_soil_for_cover_crops_produce)
|
|
136
|
+
self.percentage_of_straw_returned_to_soil_for_cover_crops = FarmSettingsVar(
|
|
137
|
+
name="Percentage Of Straw Returned To Soil For Cover Crops",
|
|
138
|
+
value=percentage_of_straw_returned_to_soil_for_cover_crops)
|
|
139
|
+
self.percentage_of_roots_returned_to_soil_for_cover_crops = FarmSettingsVar(
|
|
140
|
+
name="Percentage Of Roots Returned To Soil For Cover Crops",
|
|
141
|
+
value=percentage_of_roots_returned_to_soil_for_cover_crops)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
class ParamsRootCrops(ParamGeneric):
|
|
145
|
+
def __init__(
|
|
146
|
+
self,
|
|
147
|
+
percentage_of_product_returned_to_soil_for_root_crops: int | float = 0,
|
|
148
|
+
percentage_of_straw_returned_to_soil_for_root_crops: int | float = 100,
|
|
149
|
+
**kwargs
|
|
150
|
+
):
|
|
151
|
+
super().__init__(title="Root Crops")
|
|
152
|
+
|
|
153
|
+
self.percentage_of_product_returned_to_soil_for_root_crops = FarmSettingsVar(
|
|
154
|
+
name="Percentage Of Product Returned To Soil For Root Crops",
|
|
155
|
+
value=percentage_of_product_returned_to_soil_for_root_crops)
|
|
156
|
+
self.percentage_of_straw_returned_to_soil_for_root_crops = FarmSettingsVar(
|
|
157
|
+
name="Percentage Of Straw Returned To Soil For Root Crops",
|
|
158
|
+
value=percentage_of_straw_returned_to_soil_for_root_crops)
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
class ParamsPerennialCrops(ParamGeneric):
|
|
162
|
+
def __init__(
|
|
163
|
+
self,
|
|
164
|
+
percentage_of_product_returned_to_soil_for_perennials: int | float = 35,
|
|
165
|
+
percentage_of_roots_returned_to_soil_for_perennials: int | float = 100,
|
|
166
|
+
**kwargs
|
|
167
|
+
):
|
|
168
|
+
super().__init__(title="Perennial Crops")
|
|
169
|
+
|
|
170
|
+
self.percentage_of_product_returned_to_soil_for_perennials = FarmSettingsVar(
|
|
171
|
+
name="Percentage Of Product Returned To Soil For Perennials",
|
|
172
|
+
value=percentage_of_product_returned_to_soil_for_perennials)
|
|
173
|
+
self.percentage_of_roots_returned_to_soil_for_perennials = FarmSettingsVar(
|
|
174
|
+
name="Percentage Of Roots Returned To Soil For Perennials",
|
|
175
|
+
value=percentage_of_roots_returned_to_soil_for_perennials)
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
class ParamsRangeland(ParamGeneric):
|
|
179
|
+
def __init__(
|
|
180
|
+
self,
|
|
181
|
+
percentage_of_product_returned_to_soil_for_rangeland_due_to_harvest_loss: int | float = 35,
|
|
182
|
+
percentage_of_roots_returned_to_soil_for_rangeland: int | float = 100,
|
|
183
|
+
**kwargs
|
|
184
|
+
):
|
|
185
|
+
super().__init__(title="Rangeland")
|
|
186
|
+
self.percentage_of_product_returned_to_soil_for_rangeland_due_to_harvest_loss = FarmSettingsVar(
|
|
187
|
+
name="Percentage Of Product Returned To Soil For Rangeland Due To Harvest Loss",
|
|
188
|
+
value=percentage_of_product_returned_to_soil_for_rangeland_due_to_harvest_loss)
|
|
189
|
+
self.percentage_of_roots_returned_to_soil_for_rangeland = FarmSettingsVar(
|
|
190
|
+
name="Percentage Of Roots Returned To Soil For Rangeland",
|
|
191
|
+
value=percentage_of_roots_returned_to_soil_for_rangeland)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
class ParamsFodderCorn(ParamGeneric):
|
|
195
|
+
def __init__(
|
|
196
|
+
self,
|
|
197
|
+
run_in_period_years: int,
|
|
198
|
+
percentage_of_product_returned_to_soil_for_fodder_corn: int | float = 35,
|
|
199
|
+
percentage_of_roots_returned_to_soil_for_fodder_corn: int | float = 100,
|
|
200
|
+
decomposition_rate_constant_young_pool: float = 0.8,
|
|
201
|
+
decomposition_rate_constant_old_pool: float = 0.00605,
|
|
202
|
+
old_pool_carbon_n: float = 0.1,
|
|
203
|
+
no_ratio: float = 0.1,
|
|
204
|
+
emission_factor_for_leaching_and_runoff: float = 0.011,
|
|
205
|
+
emission_factor_for_volatilization: float = 0.01,
|
|
206
|
+
fraction_of_n_lost_by_volatilization: float = 0.21,
|
|
207
|
+
microbe_death: float = 0.2,
|
|
208
|
+
denitrification: float = 0.5,
|
|
209
|
+
**kwargs
|
|
210
|
+
):
|
|
211
|
+
super().__init__(title="Fodder Corn")
|
|
212
|
+
self.percentage_of_product_returned_to_soil_for_fodder_corn = FarmSettingsVar(
|
|
213
|
+
name="Percentage Of Product Returned To Soil For Fodder Corn",
|
|
214
|
+
value=percentage_of_product_returned_to_soil_for_fodder_corn)
|
|
215
|
+
self.percentage_of_roots_returned_to_soil_for_fodder_corn = FarmSettingsVar(
|
|
216
|
+
name="Percentage Of Roots Returned To Soil For Fodder Corn",
|
|
217
|
+
value=percentage_of_roots_returned_to_soil_for_fodder_corn)
|
|
218
|
+
self.decomposition_rate_constant_young_pool = FarmSettingsVar(
|
|
219
|
+
name="Decomposition Rate Constant Young Pool",
|
|
220
|
+
value=decomposition_rate_constant_young_pool)
|
|
221
|
+
self.decomposition_rate_constant_old_pool = FarmSettingsVar(
|
|
222
|
+
name="Decomposition Rate Constant Old Pool",
|
|
223
|
+
value=decomposition_rate_constant_old_pool)
|
|
224
|
+
self.old_pool_carbon_n = FarmSettingsVar(
|
|
225
|
+
name="Old Pool Carbon N",
|
|
226
|
+
value=old_pool_carbon_n)
|
|
227
|
+
self.no_ratio = FarmSettingsVar(
|
|
228
|
+
name="NO Ratio",
|
|
229
|
+
value=no_ratio)
|
|
230
|
+
self.emission_factor_for_leaching_and_runoff = FarmSettingsVar(
|
|
231
|
+
name="Emission Factor For Leaching And Runoff (kg N2O-N (kg N)^-1)",
|
|
232
|
+
value=emission_factor_for_leaching_and_runoff)
|
|
233
|
+
self.emission_factor_for_volatilization = FarmSettingsVar(
|
|
234
|
+
name="Emission Factor For Volatilization (kg N2O-N (kg N)^-1)",
|
|
235
|
+
value=emission_factor_for_volatilization)
|
|
236
|
+
self.fraction_of_n_lost_by_volatilization = FarmSettingsVar(
|
|
237
|
+
name="Fraction Of N Lost By Volatilization",
|
|
238
|
+
value=fraction_of_n_lost_by_volatilization)
|
|
239
|
+
self.microbe_death = FarmSettingsVar(
|
|
240
|
+
name="Microbe Death",
|
|
241
|
+
value=microbe_death)
|
|
242
|
+
self.denitrification = FarmSettingsVar(
|
|
243
|
+
name="Denitrification",
|
|
244
|
+
value=denitrification)
|
|
245
|
+
self.carbon_modelling_strategy = FarmSettingsVar(
|
|
246
|
+
name="Carbon modelling strategy",
|
|
247
|
+
value=CarbonModellingStrategies.ICBM.name)
|
|
248
|
+
self.run_in_period_years = FarmSettingsVar(
|
|
249
|
+
name="Run In Period Years",
|
|
250
|
+
value=run_in_period_years)
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
class ParamsIcbm(ParamGeneric):
|
|
254
|
+
def __init__(
|
|
255
|
+
self,
|
|
256
|
+
humification_coefficient_above_ground: float = 0.125,
|
|
257
|
+
humification_coefficient_below_ground: float = 0.3,
|
|
258
|
+
humification_coefficient_manure: float = 0.31,
|
|
259
|
+
climate_filename: str = "climate.csv",
|
|
260
|
+
climate_data_acquisition: str = "NASA",
|
|
261
|
+
enable_carbon_modelling: bool = True,
|
|
262
|
+
**kwargs
|
|
263
|
+
):
|
|
264
|
+
super().__init__(title="ICBM/Climate")
|
|
265
|
+
self.humification_coefficient_above_ground = FarmSettingsVar(
|
|
266
|
+
name="Humification Coefficient Above Ground",
|
|
267
|
+
value=humification_coefficient_above_ground)
|
|
268
|
+
self.humification_coefficient_below_ground = FarmSettingsVar(
|
|
269
|
+
name="Humification Coefficient Below Ground",
|
|
270
|
+
value=humification_coefficient_below_ground)
|
|
271
|
+
self.humification_coefficient_manure = FarmSettingsVar(
|
|
272
|
+
name="Humification Coefficient Manure",
|
|
273
|
+
value=humification_coefficient_manure)
|
|
274
|
+
self.climate_filename = FarmSettingsVar(
|
|
275
|
+
name="Climate filename",
|
|
276
|
+
value=climate_filename)
|
|
277
|
+
self.climate_data_acquisition = FarmSettingsVar(
|
|
278
|
+
name="Climate Data Acquisition",
|
|
279
|
+
value=climate_data_acquisition)
|
|
280
|
+
self.use_climate_parameter_instead_of_management_factor = FarmSettingsVar(
|
|
281
|
+
name="Use climate parameter instead of management factor",
|
|
282
|
+
value=True)
|
|
283
|
+
self.enable_carbon_modelling = FarmSettingsVar(
|
|
284
|
+
name="Enable Carbon Modelling",
|
|
285
|
+
value=enable_carbon_modelling)
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
class MonthlyWeather(ParamGeneric):
|
|
289
|
+
def __init__(
|
|
290
|
+
self,
|
|
291
|
+
title: str,
|
|
292
|
+
variable_name: str,
|
|
293
|
+
variable_monthly_values: list[int | float],
|
|
294
|
+
months_of_growing_season: list[str] = ("may", "june", "july", "august", "september", "october"),
|
|
295
|
+
**kwargs
|
|
296
|
+
):
|
|
297
|
+
super().__init__(title=title)
|
|
298
|
+
|
|
299
|
+
self._months_of_growing_season = months_of_growing_season
|
|
300
|
+
self._months = ["january", "february", "march", "april", "may", "june",
|
|
301
|
+
"july", "august", "september", "october", "november", "december"]
|
|
302
|
+
for month, value in zip(self._months, variable_monthly_values):
|
|
303
|
+
setattr(self, month, FarmSettingsVar(name=f'{month.capitalize()} {variable_name}', value=value))
|
|
304
|
+
|
|
305
|
+
def calc_seasonal_sum(self) -> float:
|
|
306
|
+
return sum([getattr(self, month).value for month in self._months_of_growing_season])
|
|
307
|
+
|
|
308
|
+
def calc_seasonal_average(self) -> float:
|
|
309
|
+
return self.calc_seasonal_sum() / len(self._months_of_growing_season)
|
|
310
|
+
|
|
311
|
+
def calc_annual_sum(self) -> float:
|
|
312
|
+
return sum([getattr(self, month).value for month in self._months])
|
|
313
|
+
|
|
314
|
+
def calc_annual_average(self) -> float:
|
|
315
|
+
return sum([getattr(self, month).value for month in self._months]) / 12.
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
class ParamsSoil(ParamGeneric):
|
|
319
|
+
def __init__(
|
|
320
|
+
self,
|
|
321
|
+
year: int,
|
|
322
|
+
**kwargs
|
|
323
|
+
):
|
|
324
|
+
super().__init__(title="Soil Data")
|
|
325
|
+
|
|
326
|
+
self.province = FarmSettingsVar(name="Province", value=kwargs['province'])
|
|
327
|
+
self.year = FarmSettingsVar(name="Year Of Observation", value=year)
|
|
328
|
+
self.ecodistrict_id = FarmSettingsVar(name="Ecodistrict ID", value=kwargs['ecodistrict_id'])
|
|
329
|
+
self.soil_great_group = FarmSettingsVar(
|
|
330
|
+
name="Soil Great Group", value=kwargs['soil_great_group'])
|
|
331
|
+
self.soil_functional_category = FarmSettingsVar(
|
|
332
|
+
name="Soil functional category", value=kwargs['soil_functional_category'])
|
|
333
|
+
self.bulk_density = FarmSettingsVar(
|
|
334
|
+
name="Bulk Density", value=kwargs['bulk_density'])
|
|
335
|
+
self.soil_texture = FarmSettingsVar(
|
|
336
|
+
name="Soil Texture", value=kwargs['soil_texture'])
|
|
337
|
+
self.soil_ph = FarmSettingsVar(
|
|
338
|
+
name="Soil Ph", value=kwargs['soil_ph'])
|
|
339
|
+
self.top_layer_thickness = FarmSettingsVar(
|
|
340
|
+
name="Top Layer Thickness (mm)", value=kwargs['top_layer_thickness'])
|
|
341
|
+
self.proportion_of_sand_in_soil = FarmSettingsVar(
|
|
342
|
+
name="Proportion Of Sand In Soil", value=kwargs['sand_proportion'])
|
|
343
|
+
self.proportion_of_clay_in_soil = FarmSettingsVar(
|
|
344
|
+
name="Proportion Of Clay In Soil", value=kwargs['clay_proportion'])
|
|
345
|
+
self.proportion_of_soil_organic_carbon = FarmSettingsVar(
|
|
346
|
+
name="Proportion Of Soil Organic Carbon", value=kwargs['organic_carbon_proportion'])
|
|
347
|
+
|
|
348
|
+
|
|
349
|
+
class ParamsFarmSettings:
|
|
350
|
+
def __init__(
|
|
351
|
+
self,
|
|
352
|
+
year: int,
|
|
353
|
+
latitude: float,
|
|
354
|
+
longitude: float,
|
|
355
|
+
monthly_precipitation: list,
|
|
356
|
+
monthly_potential_evapotranspiration: list,
|
|
357
|
+
monthly_temperature: list,
|
|
358
|
+
|
|
359
|
+
run_in_period_years: int = Defaults.DefaultRunInPeriod,
|
|
360
|
+
|
|
361
|
+
carbon_concentration: float = CoreConstants.CarbonConcentration,
|
|
362
|
+
emergence_day: int = Defaults.EmergenceDay,
|
|
363
|
+
ripening_day: int = Defaults.RipeningDay,
|
|
364
|
+
variance: int | float = Defaults.Variance,
|
|
365
|
+
alfa: float = Defaults.Alfa,
|
|
366
|
+
decomposition_minimum_temperature: float = Defaults.DecompositionMinimumTemperature,
|
|
367
|
+
decomposition_maximum_temperature: float = Defaults.DecompositionMaximumTemperature,
|
|
368
|
+
moisture_response_function_at_saturation: float = Defaults.MoistureResponseFunctionAtSaturation,
|
|
369
|
+
moisture_response_function_at_wilting_point: float = Defaults.MoistureResponseFunctionAtWiltingPoint,
|
|
370
|
+
|
|
371
|
+
percentage_of_product_returned_to_soil_for_annuals: int | float = Defaults.PercentageOfProductReturnedToSoilForAnnuals,
|
|
372
|
+
percentage_of_straw_returned_to_soil_for_annuals: int | float = Defaults.PercentageOfStrawReturnedToSoilForAnnuals,
|
|
373
|
+
percentage_of_roots_returned_to_soil_for_annuals: int | float = Defaults.PercentageOfRootsReturnedToSoilForAnnuals,
|
|
374
|
+
|
|
375
|
+
percentage_of_product_yield_returned_to_soil_for_silage_crops: int | float = Defaults.PercentageOfProductYieldReturnedToSoilForSilageCrops,
|
|
376
|
+
percentage_of_roots_returned_to_soil_for_silage_crops: int | float = Defaults.PercentageOfRootsReturnedToSoilForSilageCrops,
|
|
377
|
+
|
|
378
|
+
percentage_of_product_yield_returned_to_soil_for_cover_crops: int | float = Defaults.PercentageOfProductYieldReturnedToSoilForCoverCrops,
|
|
379
|
+
percentage_of_product_yield_returned_to_soil_for_cover_crops_forage: int | float = Defaults.PercentageOfProductYieldReturnedToSoilForCoverCropsForage,
|
|
380
|
+
percentage_of_product_yield_returned_to_soil_for_cover_crops_produce: int | float = Defaults.PercentageOfProductYieldReturnedToSoilForCoverCropsProduce,
|
|
381
|
+
percentage_of_straw_returned_to_soil_for_cover_crops: int | float = Defaults.PercentageOfStrawReturnedToSoilForCoverCrops,
|
|
382
|
+
percentage_of_roots_returned_to_soil_for_cover_crops: int | float = Defaults.PercentageOfRootsReturnedToSoilForCoverCrops,
|
|
383
|
+
|
|
384
|
+
percentage_of_product_returned_to_soil_for_root_crops: int | float = Defaults.PercentageOfProductReturnedToSoilForRootCrops,
|
|
385
|
+
percentage_of_straw_returned_to_soil_for_root_crops: int | float = Defaults.PercentageOfStrawReturnedToSoilForRootCrops,
|
|
386
|
+
|
|
387
|
+
percentage_of_product_returned_to_soil_for_perennials: int | float = Defaults.PercentageOfProductReturnedToSoilForPerennials,
|
|
388
|
+
percentage_of_roots_returned_to_soil_for_perennials: int | float = Defaults.PercentageOfRootsReturnedToSoilForPerennials,
|
|
389
|
+
|
|
390
|
+
percentage_of_product_returned_to_soil_for_rangeland_due_to_harvest_loss: int | float = Defaults.PercentageOfProductReturnedToSoilForRangelandDueToHarvestLoss,
|
|
391
|
+
percentage_of_roots_returned_to_soil_for_rangeland: int | float = Defaults.PercentageOfRootsReturnedToSoilForRangeland,
|
|
392
|
+
|
|
393
|
+
percentage_of_product_returned_to_soil_for_fodder_corn: int | float = Defaults.PercentageOfProductReturnedToSoilForFodderCorn,
|
|
394
|
+
percentage_of_roots_returned_to_soil_for_fodder_corn: int | float = Defaults.PercentageOfRootsReturnedToSoilForFodderCorn,
|
|
395
|
+
decomposition_rate_constant_young_pool: float = Defaults.DecompositionRateConstantYoungPool,
|
|
396
|
+
decomposition_rate_constant_old_pool: float = Defaults.DecompositionRateConstantOldPool,
|
|
397
|
+
old_pool_carbon_n: float = Defaults.OldPoolCarbonN,
|
|
398
|
+
no_ratio: float = Defaults.NORatio,
|
|
399
|
+
emission_factor_for_leaching_and_runoff: float = Defaults.EmissionFactorForLeachingAndRunoff,
|
|
400
|
+
emission_factor_for_volatilization: float = Defaults.EmissionFactorForVolatilization,
|
|
401
|
+
fraction_of_n_lost_by_volatilization: float = Defaults.FractionOfNLostByVolatilization,
|
|
402
|
+
microbe_death: float = Defaults.MicrobeDeath,
|
|
403
|
+
denitrification: float = Defaults.Denitrification,
|
|
404
|
+
|
|
405
|
+
humification_coefficient_above_ground: float = Defaults.HumificationCoefficientAboveGround,
|
|
406
|
+
humification_coefficient_below_ground: float = Defaults.HumificationCoefficientBelowGround,
|
|
407
|
+
humification_coefficient_manure: float = Defaults.HumificationCoefficientManure,
|
|
408
|
+
climate_filename: str = "climate.csv",
|
|
409
|
+
climate_data_acquisition: str = ChosenClimateAcquisition.NASA.name,
|
|
410
|
+
enable_carbon_modelling: bool = True,
|
|
411
|
+
):
|
|
412
|
+
"""
|
|
413
|
+
|
|
414
|
+
Args:
|
|
415
|
+
year: year of observation
|
|
416
|
+
latitude: (decimal degrees) latitude of the farm centroid
|
|
417
|
+
longitude: (decimal degrees) longitude of the farm centroid
|
|
418
|
+
monthly_precipitation: (mm) precipitation sum for each month of the year
|
|
419
|
+
monthly_potential_evapotranspiration: (mm) potential precipitation sum for each month of the year
|
|
420
|
+
monthly_temperature: (mm) air temperature average for each month of the year
|
|
421
|
+
run_in_period_years: number of simulated years for carbon modelling
|
|
422
|
+
carbon_concentration: (kg kg-1) carbon concentration in soil
|
|
423
|
+
|
|
424
|
+
emergence_day:
|
|
425
|
+
ripening_day:
|
|
426
|
+
variance:
|
|
427
|
+
alfa:
|
|
428
|
+
decomposition_minimum_temperature:
|
|
429
|
+
decomposition_maximum_temperature:
|
|
430
|
+
moisture_response_function_at_saturation:
|
|
431
|
+
moisture_response_function_at_wilting_point:
|
|
432
|
+
|
|
433
|
+
percentage_of_product_returned_to_soil_for_annuals: [0, 100] product returned to soil for annuals
|
|
434
|
+
percentage_of_straw_returned_to_soil_for_annuals: [0, 100] straw returned to soil for annuals
|
|
435
|
+
percentage_of_roots_returned_to_soil_for_annuals: [0, 100] roots returned to soil for annuals
|
|
436
|
+
percentage_of_product_yield_returned_to_soil_for_silage_crops: [0, 100] product returned to soil for silage corn
|
|
437
|
+
percentage_of_roots_returned_to_soil_for_silage_crops: [0, 100] roots returned to soil for silage corn
|
|
438
|
+
percentage_of_product_yield_returned_to_soil_for_cover_crops: [0, 100] product returned to soil for cover crops
|
|
439
|
+
percentage_of_product_yield_returned_to_soil_for_cover_crops_forage: [0, 100] product returned to soil for cover crops forage
|
|
440
|
+
percentage_of_product_yield_returned_to_soil_for_cover_crops_produce: [0, 100] product returned to soil for cover crops produce
|
|
441
|
+
percentage_of_straw_returned_to_soil_for_cover_crops: [0, 100] straw returned to soil for cover crops
|
|
442
|
+
percentage_of_roots_returned_to_soil_for_cover_crops: [0, 100] roots returned to soil for cover crops
|
|
443
|
+
percentage_of_product_returned_to_soil_for_root_crops: [0, 100] product returned to soil for root crops
|
|
444
|
+
percentage_of_straw_returned_to_soil_for_root_crops: [0, 100] straw returned to soil for root crops
|
|
445
|
+
percentage_of_product_returned_to_soil_for_perennials: [0, 100] product returned to soil for perennials
|
|
446
|
+
percentage_of_roots_returned_to_soil_for_perennials: [0, 100] roots returned to soil for perennials
|
|
447
|
+
percentage_of_product_returned_to_soil_for_rangeland_due_to_harvest_loss: [0, 100] product returned to soil for rangeland
|
|
448
|
+
percentage_of_roots_returned_to_soil_for_rangeland: [0, 100] product returned to soil for rangeland
|
|
449
|
+
percentage_of_product_returned_to_soil_for_fodder_corn: [0, 100] product returned to soil for fodder corn
|
|
450
|
+
percentage_of_roots_returned_to_soil_for_fodder_corn: [0, 100] roots returned to soil for fodder corn
|
|
451
|
+
|
|
452
|
+
decomposition_rate_constant_young_pool: (?) Decomposition Rate Constant Young Pool
|
|
453
|
+
decomposition_rate_constant_old_pool:
|
|
454
|
+
old_pool_carbon_n:
|
|
455
|
+
no_ratio:
|
|
456
|
+
|
|
457
|
+
emission_factor_for_leaching_and_runoff: (kg(N2O-N) kg(N)-1) emission factor for leaching and runoff
|
|
458
|
+
emission_factor_for_volatilization: (kg(N2O-N) kg(N)-1) emission factor for volatilization
|
|
459
|
+
|
|
460
|
+
fraction_of_n_lost_by_volatilization: (?) Fraction Of N Lost By Volatilization
|
|
461
|
+
microbe_death:
|
|
462
|
+
denitrification:
|
|
463
|
+
|
|
464
|
+
humification_coefficient_above_ground:
|
|
465
|
+
humification_coefficient_below_ground:
|
|
466
|
+
humification_coefficient_manure:
|
|
467
|
+
|
|
468
|
+
climate_filename: name of the file containing the climate data (e.g. "climate.csv")
|
|
469
|
+
climate_data_acquisition: name of the provider of climate data (e.g. "NASA")
|
|
470
|
+
enable_carbon_modelling: whether to enable carbon modelling with ICBM (default to True)
|
|
471
|
+
|
|
472
|
+
Notes:
|
|
473
|
+
The carbon modelling strategy can be one of ["IPCCTier2", "ICBM"]. In this first version, this parameter is forced to "ICBM".
|
|
474
|
+
|
|
475
|
+
"""
|
|
476
|
+
|
|
477
|
+
kwargs = {k: v for k, v in locals().items() if all([not k.startswith(('_', '__', 'self')), not callable(k)])}
|
|
478
|
+
|
|
479
|
+
soil_properties = set_soil_properties(
|
|
480
|
+
latitude=latitude,
|
|
481
|
+
longitude=longitude)
|
|
482
|
+
|
|
483
|
+
self.params_general = ParamsGeneral(
|
|
484
|
+
polygon_id=soil_properties.pop('id_polygon'),
|
|
485
|
+
**kwargs)
|
|
486
|
+
|
|
487
|
+
# Annual Crops
|
|
488
|
+
self.params_annual_crops = ParamsAnnualCrops(**kwargs)
|
|
489
|
+
|
|
490
|
+
# Silage Crops
|
|
491
|
+
self.params_silage_crops = ParamsSilageCrops(**kwargs)
|
|
492
|
+
|
|
493
|
+
# Cover Crops
|
|
494
|
+
self.params_cover_crops = ParamsCoverCrops(**kwargs)
|
|
495
|
+
|
|
496
|
+
# Root crops
|
|
497
|
+
self.params_root_crops = ParamsRootCrops(**kwargs)
|
|
498
|
+
|
|
499
|
+
# Perennial Crops
|
|
500
|
+
self.params_perennial_crops = ParamsPerennialCrops(**kwargs)
|
|
501
|
+
|
|
502
|
+
# Rangeland
|
|
503
|
+
self.params_rangeland = ParamsRangeland(**kwargs)
|
|
504
|
+
|
|
505
|
+
# Fodder Corn
|
|
506
|
+
self.params_fodder_corn = ParamsFodderCorn(**kwargs)
|
|
507
|
+
|
|
508
|
+
# ICBM/Climate
|
|
509
|
+
self.params_icbm = ParamsIcbm(**kwargs)
|
|
510
|
+
|
|
511
|
+
# Precipitation Data (mm)
|
|
512
|
+
self.params_weather_precipitation = MonthlyWeather(
|
|
513
|
+
title="Precipitation Data (mm)",
|
|
514
|
+
variable_name="Precipitation",
|
|
515
|
+
variable_monthly_values=[int(round(v, 0)) for v in monthly_precipitation])
|
|
516
|
+
|
|
517
|
+
# Precipitation Data (mm)
|
|
518
|
+
self.params_weather_potential_evapotranspiration = MonthlyWeather(
|
|
519
|
+
title="Evapotranspiration Data (mm year^-1)",
|
|
520
|
+
variable_name="Potential Evapotranspiration",
|
|
521
|
+
variable_monthly_values=[int(round(v, 0)) for v in monthly_potential_evapotranspiration])
|
|
522
|
+
|
|
523
|
+
# Temperature Data (°C)
|
|
524
|
+
self.params_weather_temperature = MonthlyWeather(
|
|
525
|
+
title="Temperature Data (°C)",
|
|
526
|
+
variable_name="Mean Temperature",
|
|
527
|
+
variable_monthly_values=[round(v, 2) for v in monthly_temperature])
|
|
528
|
+
|
|
529
|
+
# Soil Data
|
|
530
|
+
self.params_soil = ParamsSoil(
|
|
531
|
+
year=year,
|
|
532
|
+
**soil_properties)
|
|
533
|
+
|
|
534
|
+
def get_params(self) -> list[ParamGeneric]:
|
|
535
|
+
return [getattr(self, v) for v in self.__dict__ if all([not v.startswith(('_', '__')), not callable(v)])]
|
|
536
|
+
|
|
537
|
+
def write(self, path_dir_farm: Path):
|
|
538
|
+
sections = self.get_params()
|
|
539
|
+
res = [x for y in [v.to_list() + [''] for v in sections[:-1]] for x in y] + sections[-1].to_list()
|
|
540
|
+
with (path_dir_farm / 'Farm.settings').open(mode='w', encoding='utf-8') as f:
|
|
541
|
+
f.writelines('\n'.join(res))
|
|
542
|
+
pass
|
pyholos/launching.py
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import subprocess
|
|
2
|
+
from pathlib import Path, PureWindowsPath
|
|
3
|
+
|
|
4
|
+
from pyholos.config import PATH_HOLOS_CLI
|
|
5
|
+
from pyholos.utils import print_holos_msg
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def set_cmd(
|
|
9
|
+
path_dir_farms: Path,
|
|
10
|
+
path_dir_outputs: Path = None,
|
|
11
|
+
name_farm_json: str = None,
|
|
12
|
+
name_dir_farms_json: str = None,
|
|
13
|
+
name_settings: str = None,
|
|
14
|
+
id_slc_polygon: int = None,
|
|
15
|
+
) -> list[str]:
|
|
16
|
+
cmd = [
|
|
17
|
+
'cmd', '/c',
|
|
18
|
+
str(PureWindowsPath(PATH_HOLOS_CLI)),
|
|
19
|
+
str(PureWindowsPath(path_dir_farms)),
|
|
20
|
+
'-u',
|
|
21
|
+
'metric'
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
if path_dir_outputs is not None:
|
|
25
|
+
cmd += ['-o', path_dir_outputs]
|
|
26
|
+
|
|
27
|
+
if name_farm_json is not None:
|
|
28
|
+
cmd += ['-i', name_farm_json]
|
|
29
|
+
|
|
30
|
+
if name_dir_farms_json is not None:
|
|
31
|
+
cmd += ['-f', name_dir_farms_json]
|
|
32
|
+
|
|
33
|
+
if name_settings is not None:
|
|
34
|
+
if any([name_farm_json is not None, name_dir_farms_json is not None]):
|
|
35
|
+
cmd += ['-s', name_settings]
|
|
36
|
+
|
|
37
|
+
if id_slc_polygon is not None:
|
|
38
|
+
cmd += ['-p', str(int(id_slc_polygon))]
|
|
39
|
+
|
|
40
|
+
return cmd
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def launch_holos(
|
|
44
|
+
path_dir_farms: Path,
|
|
45
|
+
path_dir_outputs: Path = None,
|
|
46
|
+
name_farm_json: str = None,
|
|
47
|
+
name_dir_farms_json: str = None,
|
|
48
|
+
name_settings: str = None,
|
|
49
|
+
id_slc_polygon: int = None,
|
|
50
|
+
is_print_holos_messages: bool = False
|
|
51
|
+
) -> None:
|
|
52
|
+
cmd = set_cmd(
|
|
53
|
+
path_dir_farms=path_dir_farms,
|
|
54
|
+
path_dir_outputs=path_dir_outputs,
|
|
55
|
+
name_farm_json=name_farm_json,
|
|
56
|
+
name_dir_farms_json=name_dir_farms_json,
|
|
57
|
+
name_settings=name_settings,
|
|
58
|
+
id_slc_polygon=id_slc_polygon
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
process = subprocess.Popen(
|
|
62
|
+
cmd,
|
|
63
|
+
stdin=subprocess.PIPE,
|
|
64
|
+
stdout=subprocess.PIPE,
|
|
65
|
+
stderr=subprocess.PIPE,
|
|
66
|
+
text=True)
|
|
67
|
+
|
|
68
|
+
for msg in _get_cli_messages(p=process):
|
|
69
|
+
print_holos_msg(is_print_message=is_print_holos_messages, holos_message=msg)
|
|
70
|
+
|
|
71
|
+
if msg.startswith("Do you have farms that you would like to import from the Holos GUI? (yes/no)"):
|
|
72
|
+
process.stdin.write('no\n')
|
|
73
|
+
process.stdin.flush()
|
|
74
|
+
if "press enter to exit" in msg:
|
|
75
|
+
process.stdin.write('\n')
|
|
76
|
+
process.stdin.flush()
|
|
77
|
+
pass
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def _get_cli_messages(p: subprocess.Popen) -> str:
|
|
81
|
+
while True:
|
|
82
|
+
# returns None while subprocess is running
|
|
83
|
+
return_code = p.poll()
|
|
84
|
+
yield p.stdout.readline()
|
|
85
|
+
if return_code is not None:
|
|
86
|
+
break
|
|
File without changes
|