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.

Files changed (55) hide show
  1. pyholos/__init__.py +0 -0
  2. pyholos/common.py +141 -0
  3. pyholos/common2.py +157 -0
  4. pyholos/components/__init__.py +0 -0
  5. pyholos/components/animals/__init__.py +0 -0
  6. pyholos/components/animals/beef.py +766 -0
  7. pyholos/components/animals/common.py +2301 -0
  8. pyholos/components/animals/dairy.py +341 -0
  9. pyholos/components/animals/sheep.py +412 -0
  10. pyholos/components/common.py +170 -0
  11. pyholos/components/land_management/__init__.py +0 -0
  12. pyholos/components/land_management/carbon/__init__.py +0 -0
  13. pyholos/components/land_management/carbon/climate.py +863 -0
  14. pyholos/components/land_management/carbon/management.py +21 -0
  15. pyholos/components/land_management/carbon/relative_biomass_information.py +410 -0
  16. pyholos/components/land_management/carbon/tillage.py +88 -0
  17. pyholos/components/land_management/common.py +220 -0
  18. pyholos/components/land_management/crop.py +1233 -0
  19. pyholos/components/land_management/field_system.py +458 -0
  20. pyholos/components/land_management/utils.py +66 -0
  21. pyholos/config.py +49 -0
  22. pyholos/core_constants.py +20 -0
  23. pyholos/defaults.py +116 -0
  24. pyholos/farm/__init__.py +0 -0
  25. pyholos/farm/enums.py +54 -0
  26. pyholos/farm/farm.py +101 -0
  27. pyholos/farm/farm_inputs.py +633 -0
  28. pyholos/farm/farm_settings.py +542 -0
  29. pyholos/launching.py +86 -0
  30. pyholos/postprocessing/__init__.py +0 -0
  31. pyholos/postprocessing/plots.py +164 -0
  32. pyholos/postprocessing/postprocessing.py +38 -0
  33. pyholos/resources/holos/Table_16_Livestock_Coefficients_BeefAndDairy_Cattle_Provider.csv +21 -0
  34. pyholos/resources/holos/Table_21_Average_Milk_Production_For_Dairy_Cows_By_Province.csv +23 -0
  35. pyholos/resources/holos/Table_22_Livestock_Coefficients_For_Sheep.csv +28 -0
  36. pyholos/resources/holos/Table_29_Percentage_Total_Manure_Produced_In_Systems.csv +56 -0
  37. pyholos/resources/holos/Table_30_Default_Bedding_Material_Composition_Provider.csv +28 -0
  38. pyholos/resources/holos/Table_50_Fuel_Energy_Requirement_Estimates_By_Region.csv +81 -0
  39. pyholos/resources/holos/Table_51_Herbicide_Energy_Requirement_Estimates_By_Region.csv +81 -0
  40. pyholos/resources/holos/Table_61_Fractions_of_dairy_cattle_N_volatilized.csv +25 -0
  41. pyholos/resources/holos/Table_62_Fractions_of_swine_N_volatilized.csv +25 -0
  42. pyholos/resources/holos/Table_6_Manure_Types_And_Default_Composition.csv +126 -0
  43. pyholos/resources/holos/Table_7_Relative_Biomass_Information.csv +112 -0
  44. pyholos/resources/holos/Table_9_Default_Values_For_Nitrogen_Lignin_In_Crops.csv +72 -0
  45. pyholos/resources/holos/Table_Tillage_Factor.csv +13 -0
  46. pyholos/resources/holos/feeds.csv +223 -0
  47. pyholos/resources/holos/main_tables.py +493 -0
  48. pyholos/resources/holos/small_area_yields.csv +167159 -0
  49. pyholos/resources/soil_landscapes_of_canada_v3r2.zip +0 -0
  50. pyholos/soil.py +439 -0
  51. pyholos/utils.py +83 -0
  52. pyholos-0.0.1.dist-info/METADATA +16 -0
  53. pyholos-0.0.1.dist-info/RECORD +55 -0
  54. pyholos-0.0.1.dist-info/WHEEL +4 -0
  55. 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