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,863 @@
1
+ import math
2
+ import sys
3
+ from dataclasses import dataclass
4
+
5
+ from pyholos.core_constants import CoreConstants
6
+ from pyholos.utils import calc_average
7
+
8
+
9
+ @dataclass
10
+ class DailClimateParams:
11
+ SoilTemperature: float
12
+ SoilWaterStorage: float
13
+ ClimateParameter: float
14
+
15
+
16
+ def _get_julian_days() -> list[int]:
17
+ """Returns the number of days in a common year (non-bissextile year).
18
+
19
+ Returns:
20
+ Julian days of a common year (365 days)
21
+
22
+ Holos source code:
23
+ https://github.com/holos-aafc/Holos/blob/8a3d8fb047c2058a3dbe273f5a8550ae63a54f14/H.Core/Calculators/Climate/ClimateParameterCalculator.cs#L340
24
+ """
25
+ return list(range(1, CoreConstants.DaysInYear + 1))
26
+
27
+
28
+ def calculate_green_area_index_max(
29
+ crop_yield: float
30
+ ) -> float:
31
+ """Calculates the maximum amplitude of green area index
32
+
33
+ Args:
34
+ crop_yield: (kg(DM)/ha) crop yield
35
+
36
+ Returns:
37
+ (m2(green area)/m2(ground)) maximum amplitude of green area index
38
+
39
+ Holos source code:
40
+ https://github.com/holos-aafc/Holos/blob/8a3d8fb047c2058a3dbe273f5a8550ae63a54f14/H.Core/Calculators/Climate/ClimateParameterCalculator.cs#L443
41
+ """
42
+ return 0.0731 * (crop_yield / 1000) ** 2 + 0.408 * crop_yield / 1000
43
+
44
+
45
+ def calculate_mid_season(
46
+ emergence_day: int,
47
+ ripening_day: int
48
+ ) -> int | float:
49
+ """Calculates the maximum amplitude of green area index
50
+
51
+ Args:
52
+ emergence_day: (Julian day) day of crop emergence
53
+ ripening_day: (Julian day) day of crop ripening
54
+
55
+ Returns:
56
+ (Julian day) median day of the growing season
57
+
58
+ Holos source code:
59
+ https://github.com/holos-aafc/Holos/blob/8a3d8fb047c2058a3dbe273f5a8550ae63a54f14/H.Core/Calculators/Climate/ClimateParameterCalculator.cs#L453
60
+ """
61
+ return emergence_day + (ripening_day - emergence_day) / 2
62
+
63
+
64
+ def calculate_green_area_index(
65
+ green_area_index_max: float,
66
+ julian_day: int,
67
+ mid_season: float,
68
+ variance: float
69
+ ) -> float:
70
+ """Calculates the green area index at a given day
71
+
72
+ Args:
73
+ green_area_index_max: (m2(green area)/m2(ground)) maximum amplitude of green area index
74
+ julian_day: (julian day) day
75
+ mid_season: (Julian day) median day of the growing season
76
+ variance: width of distribution function
77
+
78
+ Returns:
79
+ (m2(green area)/m2(ground)) green area index
80
+
81
+ Holos source code:
82
+ https://github.com/holos-aafc/Holos/blob/8a3d8fb047c2058a3dbe273f5a8550ae63a54f14/H.Core/Calculators/Climate/ClimateParameterCalculator.cs#L463
83
+ """
84
+ return green_area_index_max * math.exp((-1 * (julian_day - mid_season) ** 2) / (2 * variance))
85
+
86
+
87
+ def calculate_organic_carbon_factor(
88
+ percent_organic_carbon: float
89
+ ) -> float:
90
+ """Calculates the organic carbon factor (OrgC_factor)
91
+
92
+ Args:
93
+ percent_organic_carbon: (%) percentage of organic C in soil, by weight
94
+
95
+ Returns:
96
+ (-) organic carbon factor (OrgC_factor)
97
+
98
+ Holos source code:
99
+ https://github.com/holos-aafc/Holos/blob/8a3d8fb047c2058a3dbe273f5a8550ae63a54f14/H.Core/Calculators/Climate/ClimateParameterCalculator.cs#L474
100
+ """
101
+ return -0.837531 + 0.430183 * percent_organic_carbon
102
+
103
+
104
+ def calculate_clay_factor(
105
+ clay_content: float
106
+ ) -> float:
107
+ """Calculates the clay factor
108
+
109
+ Args:
110
+ clay_content: fraction of clay in soil (between 0 and 1)
111
+
112
+ Returns:
113
+ (-) clay factor
114
+
115
+ Holos source code:
116
+ https://github.com/holos-aafc/Holos/blob/8a3d8fb047c2058a3dbe273f5a8550ae63a54f14/H.Core/Calculators/Climate/ClimateParameterCalculator.cs#L484
117
+ """
118
+ return -1.40744 + 0.0661969 * clay_content * 100
119
+
120
+
121
+ def calculate_sand_factor(
122
+ sand_content: float
123
+ ) -> float:
124
+ """Calculates the sand factor
125
+
126
+ Args:
127
+ sand_content: fraction of sand in soil (between 0 and 1)
128
+
129
+ Returns:
130
+ (-) sand factor
131
+
132
+ Holos source code:
133
+ https://github.com/holos-aafc/Holos/blob/8a3d8fb047c2058a3dbe273f5a8550ae63a54f14/H.Core/Calculators/Climate/ClimateParameterCalculator.cs#L494
134
+ """
135
+ return -1.51866 + 0.0393284 * sand_content * 100
136
+
137
+
138
+ def calculate_wilting_point(
139
+ organic_carbon_factor: float,
140
+ clay_factor: float,
141
+ sand_factor: float
142
+ ) -> float:
143
+ """Calculates the volumetric water content at wilting point
144
+
145
+ Args:
146
+ organic_carbon_factor: (-) organic carbon factor (OrgC_factor)
147
+ clay_factor: (-) clay factor
148
+ sand_factor: (-) sand factor
149
+
150
+ Returns:
151
+ (mm3/mm3) volumetric water content at wilting point
152
+
153
+ Holos source code:
154
+ https://github.com/holos-aafc/Holos/blob/8a3d8fb047c2058a3dbe273f5a8550ae63a54f14/H.Core/Calculators/Climate/ClimateParameterCalculator.cs#L504
155
+ """
156
+ wilting_point_percent = 14.2568 + 7.36318 * (
157
+ 0.06865 + 0.108713 * organic_carbon_factor -
158
+ 0.0157225 * organic_carbon_factor ** 2 +
159
+ 0.00102805 * organic_carbon_factor ** 3 +
160
+ 0.886569 * clay_factor -
161
+ 0.223581 * organic_carbon_factor * clay_factor +
162
+ 0.0126379 * organic_carbon_factor ** 2 * clay_factor -
163
+ 0.017059 * clay_factor ** 2 +
164
+ 0.0135266 * organic_carbon_factor * clay_factor ** 2 -
165
+ 0.0334434 * clay_factor ** 3 -
166
+ 0.0535182 * sand_factor -
167
+ 0.0354271 * organic_carbon_factor * sand_factor -
168
+ 0.00261313 * organic_carbon_factor ** 2 * sand_factor -
169
+ 0.154563 * clay_factor * sand_factor -
170
+ 0.0160219 * organic_carbon_factor * clay_factor * sand_factor -
171
+ 0.0400606 * clay_factor ** 2 * sand_factor -
172
+ 0.104875 * sand_factor ** 2 +
173
+ 0.0159857 * organic_carbon_factor * sand_factor ** 2 -
174
+ 0.0671656 * clay_factor * sand_factor ** 2 -
175
+ 0.0260699 * sand_factor ** 3)
176
+
177
+ return wilting_point_percent / 100.
178
+
179
+
180
+ def calculate_field_capacity(
181
+ organic_carbon_factor: float,
182
+ clay_factor: float,
183
+ sand_factor: float
184
+ ) -> float:
185
+ """Calculates the volumetric water content at field capacity
186
+
187
+ Args:
188
+ organic_carbon_factor: (-) organic carbon factor (OrgC_factor)
189
+ clay_factor: (-) clay factor
190
+ sand_factor: (-) sand factor
191
+
192
+ Returns:
193
+ (mm3/mm3) volumetric water content at field capacity
194
+
195
+ Holos source code:
196
+ https://github.com/holos-aafc/Holos/blob/8a3d8fb047c2058a3dbe273f5a8550ae63a54f14/H.Core/Calculators/Climate/ClimateParameterCalculator.cs#L543
197
+ """
198
+ field_capacity_percent = 29.7528 + 10.3544 * (
199
+ 0.0461615 + 0.290955 * organic_carbon_factor -
200
+ 0.0496845 * organic_carbon_factor * organic_carbon_factor +
201
+ 0.00704802 * organic_carbon_factor * organic_carbon_factor * organic_carbon_factor +
202
+ 0.269101 * clay_factor -
203
+ 0.176528 * organic_carbon_factor * clay_factor +
204
+ 0.0543138 * organic_carbon_factor * organic_carbon_factor * clay_factor +
205
+ 0.1982 * clay_factor * clay_factor -
206
+ 0.060699 * clay_factor * clay_factor * clay_factor -
207
+ 0.320249 * sand_factor -
208
+ 0.0111693 * organic_carbon_factor * organic_carbon_factor * sand_factor +
209
+ 0.14104 * clay_factor * sand_factor +
210
+ 0.0657345 * organic_carbon_factor * clay_factor * sand_factor -
211
+ 0.102026 * clay_factor * clay_factor * sand_factor -
212
+ 0.04012 * sand_factor * sand_factor +
213
+ 0.160838 * organic_carbon_factor * sand_factor * sand_factor -
214
+ 0.121392 * clay_factor * sand_factor * sand_factor -
215
+ 0.061667 * sand_factor * sand_factor * sand_factor)
216
+
217
+ return field_capacity_percent / 100.
218
+
219
+
220
+ def calculate_soil_mean_depth(
221
+ layer_thickness: float
222
+ ) -> float:
223
+ """Calculates the soil top layer mean depth
224
+
225
+ Args:
226
+ layer_thickness: (mm) top layer thickness
227
+
228
+ Returns:
229
+ (mm) soil top layer mean depth
230
+
231
+ Holos source code:
232
+ https://github.com/holos-aafc/Holos/blob/8a3d8fb047c2058a3dbe273f5a8550ae63a54f14/H.Core/Calculators/Climate/ClimateParameterCalculator.cs#L581
233
+
234
+ Note:
235
+ Holos assumes the value of layer_thickness constant to 250 mm
236
+ """
237
+ return layer_thickness / 20.
238
+
239
+
240
+ def calculate_leaf_area_index(
241
+ green_area_index: float
242
+ ) -> float:
243
+ """Calculates the leaf area index
244
+
245
+ Args:
246
+ green_area_index: (m2(green area)/m2(ground)) green area index
247
+
248
+ Returns:
249
+ (m2(leaf)/m2(ground)) leaf area index
250
+
251
+ Holos source code:
252
+ https://github.com/holos-aafc/Holos/blob/8a3d8fb047c2058a3dbe273f5a8550ae63a54f14/H.Core/Calculators/Climate/ClimateParameterCalculator.cs#L591
253
+ """
254
+ return 0.8 * green_area_index
255
+
256
+
257
+ def calculate_surface_temperature(
258
+ temperature: float,
259
+ leaf_area_index: float
260
+ ) -> float:
261
+ """Calculates the soil surface temperature
262
+
263
+ Args:
264
+ temperature: (degrees Celsius) daily mean air temperature by month
265
+ leaf_area_index: (m2(leaf)/m2(ground)) leaf area index
266
+
267
+ Returns:
268
+ (degrees Celsius) soil surface temperature
269
+
270
+ Holos source code:
271
+ https://github.com/holos-aafc/Holos/blob/8a3d8fb047c2058a3dbe273f5a8550ae63a54f14/H.Core/Calculators/Climate/ClimateParameterCalculator.cs#L602
272
+ """
273
+ return 0.20 * temperature if temperature < 0 else (
274
+ temperature * (0.95 + 0.05 * math.exp(-0.4 * (leaf_area_index - 3))))
275
+
276
+
277
+ def calculate_soil_temperatures(
278
+ julian_day: int,
279
+ soil_mean_depth: float,
280
+ green_area_index: float,
281
+ surface_temperature: float,
282
+ soil_temperature_previous: float
283
+ ) -> float:
284
+ """calculates the soil temperature
285
+
286
+ Args:
287
+ julian_day: (julian day) day
288
+ soil_mean_depth: (mm) soil top layer mean depth
289
+ green_area_index: (m2(green area)/m2(ground)) green area index
290
+ surface_temperature: (degrees Celsius) soil surface temperature
291
+ soil_temperature_previous: (degrees Celsius) soil surface temperature of the previous day
292
+
293
+ Returns:
294
+ (degrees Celsius) soil temperature
295
+
296
+ Holos source code:
297
+ https://github.com/holos-aafc/Holos/blob/8a3d8fb047c2058a3dbe273f5a8550ae63a54f14/H.Core/Calculators/Climate/ClimateParameterCalculator.cs#L621
298
+ """
299
+ if julian_day == 1:
300
+ current_soil_temperature = 0
301
+ else:
302
+ current_soil_temperature = soil_temperature_previous + (surface_temperature - soil_temperature_previous) * (
303
+ 0.24 * math.exp(-soil_mean_depth * 0.017) * math.exp(-0.15 * green_area_index))
304
+
305
+ return current_soil_temperature
306
+
307
+
308
+ def calculate_crop_coefficient(
309
+ green_area_index: float
310
+ ) -> float:
311
+ """Calculates the crop coefficient
312
+
313
+ Args:
314
+ green_area_index: (m2(green area)/m2(ground)) green area index
315
+
316
+ Returns:
317
+ (-) crop coefficient
318
+
319
+ Holos source code:
320
+ https://github.com/holos-aafc/Holos/blob/8a3d8fb047c2058a3dbe273f5a8550ae63a54f14/H.Core/Calculators/Climate/ClimateParameterCalculator.cs#L646
321
+ """
322
+ return 1.3 - (1.3 - 0.8) * math.exp(-0.17 * green_area_index)
323
+
324
+
325
+ def calculate_crop_evapotranspiration(
326
+ evapotranspiration: float,
327
+ crop_coefficient: float
328
+ ) -> float:
329
+ """Calculates crop evapotranspiration
330
+
331
+ Args:
332
+ evapotranspiration: (mm/d) reference crop evapotranspiration
333
+ crop_coefficient: (-) crop coefficient
334
+
335
+ Returns:
336
+ (mm/d) crop evapotranspiration
337
+
338
+ Holos source code:
339
+ https://github.com/holos-aafc/Holos/blob/8a3d8fb047c2058a3dbe273f5a8550ae63a54f14/H.Core/Calculators/Climate/ClimateParameterCalculator.cs#L656
340
+ """
341
+ return evapotranspiration * crop_coefficient
342
+
343
+
344
+ def calculate_crop_interception(
345
+ total_daily_precipitation: float,
346
+ green_area_index: float,
347
+ crop_evapotranspiration: float
348
+ ) -> float:
349
+ """Calculates crop interception
350
+
351
+ Args:
352
+ total_daily_precipitation: (mm/d) daily precipitation
353
+ green_area_index: (m2(green area)/m2(ground)) green area index
354
+ crop_evapotranspiration: (mm/d) crop evapotranspiration
355
+
356
+ Returns:
357
+ (mm/d) crop interception
358
+
359
+ Holos source code:
360
+ https://github.com/holos-aafc/Holos/blob/8a3d8fb047c2058a3dbe273f5a8550ae63a54f14/H.Core/Calculators/Climate/ClimateParameterCalculator.cs#L668
361
+ """
362
+ return min(crop_evapotranspiration, min(0.2 * green_area_index, total_daily_precipitation))
363
+
364
+
365
+ def calculate_soil_available_water(
366
+ total_daily_precipitation: float,
367
+ crop_interception: float
368
+ ) -> float:
369
+ """Calculates the available daily water for soil
370
+
371
+ Args:
372
+ total_daily_precipitation: (mm/d) total precipitation
373
+ crop_interception: (mm/d) crop interception
374
+
375
+ Returns:
376
+ (mm) available daily water for soil
377
+
378
+ Holos source code:
379
+ https://github.com/RamiALBASHA/Holos/blob/06918a38b63407808e06683036639ca4afe04332/H.Core/Calculators/Climate/ClimateParameterCalculator.cs#L694
380
+ """
381
+ return total_daily_precipitation - crop_interception
382
+
383
+
384
+ def calculate_volumetric_soil_water_content(
385
+ water_storage_previous: float,
386
+ layer_thickness: float,
387
+ wilting_point: float
388
+ ) -> float:
389
+ """Calculates the volumetric water content of soil
390
+
391
+ Args:
392
+ water_storage_previous: (mm day-1) soil available water of the previous day
393
+ layer_thickness: (mm) soil layer thickness
394
+ wilting_point: (mm3/mm3) volumetric water content at wilting point
395
+
396
+ Returns:
397
+ (mm3/mm3) volumetric water content
398
+
399
+ Holos source code:
400
+ https://github.com/holos-aafc/Holos/blob/8a3d8fb047c2058a3dbe273f5a8550ae63a54f14/H.Core/Calculators/Climate/ClimateParameterCalculator.cs#L713
401
+ """
402
+ volumetric_soil_water_content = water_storage_previous / layer_thickness
403
+
404
+ if abs(volumetric_soil_water_content) < sys.float_info.epsilon:
405
+ volumetric_soil_water_content = wilting_point
406
+
407
+ return volumetric_soil_water_content
408
+
409
+
410
+ def calculate_soil_coefficient(
411
+ field_capacity: float,
412
+ volumetric_soil_water_content: float,
413
+ wilting_point: float,
414
+ alfa: float = 0.7
415
+ ) -> float:
416
+ """Calculates the soil coefficient of the actual crop evapotranspiration
417
+
418
+ Args:
419
+ field_capacity: (mm3/mm3) volumetric water content at field capacity
420
+ volumetric_soil_water_content: (mm3/mm3) volumetric water content
421
+ wilting_point: (mm3/mm3) volumetric water content at wilting point
422
+ alfa: (-) minimum water storage fraction of wilting_point
423
+
424
+ Returns:
425
+ (-) soil coefficient for evapotranspiration
426
+
427
+ Holos source code:
428
+ https://github.com/holos-aafc/Holos/blob/8a3d8fb047c2058a3dbe273f5a8550ae63a54f14/H.Core/Calculators/Climate/ClimateParameterCalculator.cs#L732
429
+ """
430
+ soil_coefficient = min(
431
+ 1., max(0.,
432
+ (1 - (0.95 * field_capacity - volumetric_soil_water_content) / (
433
+ 0.95 * field_capacity - alfa * wilting_point)) ** 2))
434
+
435
+ return 0 if (volumetric_soil_water_content < alfa * wilting_point) else soil_coefficient
436
+
437
+
438
+ def calculate_actual_evapotranspiration(
439
+ crop_potential_evapotranspiration: float,
440
+ soil_coefficient: float
441
+ ) -> float:
442
+ """Calculates the actual evapotranspiration of the crop
443
+
444
+ Args:
445
+ crop_potential_evapotranspiration: (mm/d) crop potential evapotranspiration
446
+ soil_coefficient: (-) soil coefficient
447
+
448
+ Returns:
449
+ (mm/d) actual crop evapotranspiration
450
+
451
+ Holos source code:
452
+ https://github.com/holos-aafc/Holos/blob/8a3d8fb047c2058a3dbe273f5a8550ae63a54f14/H.Core/Calculators/Climate/ClimateParameterCalculator.cs#L762
453
+ """
454
+ return soil_coefficient * crop_potential_evapotranspiration
455
+
456
+
457
+ def calculate_deep_percolation(
458
+ field_capacity: float,
459
+ layer_thickness: float,
460
+ previous_water_storage: float
461
+ ) -> float:
462
+ """Calculates the deep percolation due to excess water beyond field capacity.
463
+
464
+ Args:
465
+ field_capacity: (mm3/mm3) volumetric water content at field capacity
466
+ layer_thickness: (mm) thickness of the soil top layer
467
+ previous_water_storage: (mm) water storage of the previous day
468
+
469
+ Returns:
470
+ (mm/d) water lost to percolation down the soil profile
471
+
472
+ Holos source code:
473
+ https://github.com/holos-aafc/Holos/blob/8a3d8fb047c2058a3dbe273f5a8550ae63a54f14/H.Core/Calculators/Climate/ClimateParameterCalculator.cs#L773
474
+ """
475
+ return max(0., previous_water_storage - field_capacity * layer_thickness)
476
+
477
+
478
+ def calculate_julian_day_water_storage(
479
+ deep_percolation: float,
480
+ previous_water_storage: float,
481
+ soil_available_water: float,
482
+ actual_evapotranspiration: float
483
+ ) -> float:
484
+ """Calculates the water storage of a given day.
485
+
486
+ Args:
487
+ deep_percolation: (mm/d) water lost to percolation down the soil profile
488
+ previous_water_storage: (mm) water storage of the previous day
489
+ soil_available_water: (mm) soil available water
490
+ actual_evapotranspiration: (mm/d) actual evapotranspiration
491
+
492
+ Returns:
493
+ (mm) soil water storage of the current day
494
+
495
+ Holos source code:
496
+ https://github.com/holos-aafc/Holos/blob/8a3d8fb047c2058a3dbe273f5a8550ae63a54f14/H.Core/Calculators/Climate/ClimateParameterCalculator.cs#L796
497
+ """
498
+ return previous_water_storage + soil_available_water - actual_evapotranspiration - deep_percolation
499
+
500
+
501
+ def calculate_temperature_response_factor(
502
+ soil_temperature_previous: float,
503
+ decomposition_minimum_temperature: float,
504
+ decomposition_maximum_temperature: float
505
+ ) -> float:
506
+ """Calculates the temperature response factor (re_temp)
507
+
508
+ Args:
509
+ soil_temperature_previous: (degree Celsius) soil temperature of the previous day
510
+ decomposition_minimum_temperature: (degree Celsius) minimum cardinal temperature
511
+ decomposition_maximum_temperature: (degree Celsius) maximum cardinal temperature
512
+
513
+ Returns:
514
+ (-) temperature response factor
515
+
516
+ Holos source code:
517
+ https://github.com/holos-aafc/Holos/blob/8a3d8fb047c2058a3dbe273f5a8550ae63a54f14/H.Core/Calculators/Climate/ClimateParameterCalculator.cs#L826
518
+ """
519
+ return 0 if soil_temperature_previous < -3.78 else (
520
+ ((soil_temperature_previous - decomposition_minimum_temperature) / (
521
+ decomposition_maximum_temperature - decomposition_minimum_temperature)) ** 2)
522
+
523
+
524
+ def calculate_moisture_response_factor(
525
+ volumetric_water_content: float,
526
+ field_capacity: float,
527
+ wilting_point: float,
528
+ reference_saturation_point: float,
529
+ reference_wilting_point: float
530
+ ) -> float:
531
+ """Calculates the water response factor (re_water)
532
+
533
+ Args:
534
+ volumetric_water_content: (mm3/mm3) soil volumetric water content
535
+ field_capacity: (mm3/mm3) soil volumetric water content at field capacity
536
+ wilting_point: (mm3/mm3) soil volumetric water content at the wilting point
537
+ reference_saturation_point: (mm3/mm3) soil volumetric water content at reference saturation
538
+ reference_wilting_point: (mm3/mm3) soil volumetric water content at reference wilting point
539
+
540
+ Returns:
541
+ (-) moisture response factor
542
+
543
+ Holos source code:
544
+ https://github.com/holos-aafc/Holos/blob/8a3d8fb047c2058a3dbe273f5a8550ae63a54f14/H.Core/Calculators/Climate/ClimateParameterCalculator.cs#L851
545
+ """
546
+ saturation_point = 1.2 * field_capacity
547
+ optimum_water_content = 0.9 * field_capacity
548
+
549
+ if volumetric_water_content > optimum_water_content:
550
+ moisture_response_factor = 1 - (1 - reference_saturation_point) * (
551
+ (volumetric_water_content - optimum_water_content) / (saturation_point - optimum_water_content))
552
+ elif volumetric_water_content >= wilting_point:
553
+ moisture_response_factor = reference_wilting_point + (1 - reference_wilting_point) * (
554
+ (volumetric_water_content - wilting_point) / (optimum_water_content - wilting_point))
555
+ else:
556
+ moisture_response_factor = reference_wilting_point * volumetric_water_content / wilting_point
557
+
558
+ return max(0., min(1., moisture_response_factor))
559
+
560
+
561
+ def calculate_climate_factor(
562
+ moisture_response_factor: float,
563
+ temperature_response_factor: float
564
+ ) -> float:
565
+ """Calculates the climate parameter (re_crop_daily)
566
+
567
+ Args:
568
+ moisture_response_factor: (-) moisture response factor
569
+ temperature_response_factor: (-) temperature response factor
570
+
571
+ Returns:
572
+ (-) climate response factor
573
+
574
+ Holos source code:
575
+ https://github.com/holos-aafc/Holos/blob/8a3d8fb047c2058a3dbe273f5a8550ae63a54f14/H.Core/Calculators/Climate/ClimateParameterCalculator.cs#L901
576
+ """
577
+ return moisture_response_factor * temperature_response_factor / 0.10516
578
+
579
+
580
+ def calculate_daily_climate_parameter(
581
+ julian_day: int,
582
+ mid_season: float,
583
+ temperature: float,
584
+ precipitation: float,
585
+ evapotranspiration: float,
586
+ variance: float,
587
+ field_capacity: float,
588
+ wilting_point: float,
589
+ layer_thickness: float,
590
+ soil_mean_depth: float,
591
+ green_area_index_max: float,
592
+ alfa: float,
593
+ decomposition_minimum_temperature: float,
594
+ decomposition_maximum_temperature: float,
595
+ moisture_response_function_at_saturation: float,
596
+ moisture_response_function_at_wilting_point: float,
597
+ soil_temperature_previous: float,
598
+ soil_water_storage_previous: float
599
+ ) -> DailClimateParams:
600
+ """Calculates the daily variables required to estimate the ClimateParameter
601
+
602
+ Args:
603
+ julian_day: Julian day
604
+ mid_season: (Julian day) median day of the growing season
605
+ temperature: (degrees Celsius) air temperature
606
+ precipitation: (mm/d) total precipitation
607
+ evapotranspiration: (mm/d) reference crop evapotranspiration
608
+ variance: width of distribution function
609
+ field_capacity: (mm3/mm3) soil volumetric water content at field capacity
610
+ wilting_point: (mm3/mm3) soil volumetric water content at the wilting point
611
+ layer_thickness: (mm) thickness of the soil top layer
612
+ soil_mean_depth: (mm) soil top layer mean depth
613
+ green_area_index_max: (m2(green area)/m2(ground)) maximum amplitude of green area index
614
+ alfa: (-) minimum water storage fraction of wilting_point
615
+ decomposition_minimum_temperature: (degree Celsius) minimum cardinal temperature for decomposition
616
+ decomposition_maximum_temperature: (degree Celsius) maximum cardinal temperature for decomposition
617
+ moisture_response_function_at_saturation: (mm3/mm3) soil volumetric water content at reference saturation
618
+ moisture_response_function_at_wilting_point: (mm3/mm3) soil volumetric water content at reference wilting point
619
+ soil_temperature_previous: (degrees Celsius) soil surface temperature of the previous day
620
+ soil_water_storage_previous: (degrees Celsius) soil water storage of the previous day
621
+
622
+ Returns:
623
+ SoilTemperature: (degrees Celsius) soil surface temperature of the current day
624
+ SoilWaterStorage: (degrees Celsius) soil water storage of the current day
625
+ ClimateFactor: (-) climate factor of the current day
626
+
627
+ Holos source code:
628
+ https://github.com/holos-aafc/Holos/blob/8a3d8fb047c2058a3dbe273f5a8550ae63a54f14/H.Core/Calculators/Climate/ClimateParameterCalculator.cs#L348
629
+ """
630
+ green_area_index = calculate_green_area_index(
631
+ green_area_index_max=green_area_index_max,
632
+ julian_day=julian_day,
633
+ mid_season=mid_season,
634
+ variance=variance)
635
+
636
+ leaf_area_index = calculate_leaf_area_index(
637
+ green_area_index=green_area_index)
638
+
639
+ surface_temperature = calculate_surface_temperature(
640
+ temperature=temperature,
641
+ leaf_area_index=leaf_area_index)
642
+
643
+ soil_temperature_current = calculate_soil_temperatures(
644
+ julian_day=julian_day,
645
+ surface_temperature=surface_temperature,
646
+ soil_mean_depth=soil_mean_depth,
647
+ green_area_index=green_area_index,
648
+ soil_temperature_previous=soil_temperature_previous)
649
+
650
+ crop_coefficient = calculate_crop_coefficient(
651
+ green_area_index=green_area_index)
652
+
653
+ crop_evapotranspiration = calculate_crop_evapotranspiration(
654
+ evapotranspiration=evapotranspiration,
655
+ crop_coefficient=crop_coefficient)
656
+
657
+ crop_interception = calculate_crop_interception(
658
+ total_daily_precipitation=precipitation,
659
+ green_area_index=green_area_index,
660
+ crop_evapotranspiration=crop_evapotranspiration)
661
+
662
+ soil_available_water = calculate_soil_available_water(
663
+ total_daily_precipitation=precipitation,
664
+ crop_interception=crop_interception)
665
+
666
+ volumetric_soil_water_content = calculate_volumetric_soil_water_content(
667
+ water_storage_previous=soil_water_storage_previous,
668
+ layer_thickness=layer_thickness,
669
+ wilting_point=wilting_point)
670
+
671
+ soil_coefficient = calculate_soil_coefficient(
672
+ field_capacity=field_capacity,
673
+ volumetric_soil_water_content=volumetric_soil_water_content,
674
+ wilting_point=wilting_point,
675
+ alfa=alfa)
676
+
677
+ actual_evapotranspiration = calculate_actual_evapotranspiration(
678
+ crop_potential_evapotranspiration=crop_evapotranspiration,
679
+ soil_coefficient=soil_coefficient)
680
+
681
+ deep_percolation = calculate_deep_percolation(
682
+ field_capacity=field_capacity,
683
+ layer_thickness=layer_thickness,
684
+ previous_water_storage=soil_water_storage_previous)
685
+
686
+ current_water_storage = calculate_julian_day_water_storage(
687
+ deep_percolation=deep_percolation,
688
+ previous_water_storage=soil_water_storage_previous,
689
+ soil_available_water=soil_available_water,
690
+ actual_evapotranspiration=actual_evapotranspiration)
691
+
692
+ temperature_response_factor = calculate_temperature_response_factor(
693
+ soil_temperature_previous=soil_temperature_previous,
694
+ decomposition_minimum_temperature=decomposition_minimum_temperature,
695
+ decomposition_maximum_temperature=decomposition_maximum_temperature)
696
+
697
+ moisture_response_factor = calculate_moisture_response_factor(
698
+ volumetric_water_content=volumetric_soil_water_content,
699
+ field_capacity=field_capacity,
700
+ wilting_point=wilting_point,
701
+ reference_saturation_point=moisture_response_function_at_saturation,
702
+ reference_wilting_point=moisture_response_function_at_wilting_point)
703
+
704
+ climate_factor = calculate_climate_factor(
705
+ moisture_response_factor=moisture_response_factor,
706
+ temperature_response_factor=temperature_response_factor)
707
+
708
+ return DailClimateParams(
709
+ SoilTemperature=soil_temperature_current,
710
+ SoilWaterStorage=current_water_storage,
711
+ ClimateParameter=climate_factor)
712
+
713
+
714
+ def calculate_daily_climate_parameters(
715
+ emergence_day: int,
716
+ ripening_day: int,
717
+ crop_yield: float,
718
+ clay: float,
719
+ sand: float,
720
+ layer_thickness_in_millimeters: float,
721
+ percentage_soil_organic_carbon: float,
722
+ variance: float,
723
+ alfa: float,
724
+ decomposition_minimum_temperature: float,
725
+ decomposition_maximum_temperature: float,
726
+ moisture_response_function_at_wilting_point: float,
727
+ moisture_response_function_at_saturation: float,
728
+ evapotranspirations: list[float],
729
+ precipitations: list[float],
730
+ temperatures: list[float]
731
+ ) -> list[float]:
732
+ """Calculates all daily values of the climate parameter.
733
+
734
+ Args:
735
+ emergence_day: (julian day) day of plant emergence
736
+ ripening_day: (julian day) day of plant ripening
737
+ crop_yield: (kg(DM)/ha) crop yield
738
+ clay: fraction of clay in soil (between 0 and 1)
739
+ sand: fraction of sand in soil (between 0 and 1)
740
+ layer_thickness_in_millimeters: (mm) soil layer thickness
741
+ percentage_soil_organic_carbon: (%) percentage of organic C in soil (between 0 and 100), by weight
742
+ variance: width of distribution function
743
+ alfa: (-) minimum water storage fraction of wilting_point
744
+ decomposition_minimum_temperature: (degree Celsius) minimum cardinal temperature for decomposition
745
+ decomposition_maximum_temperature: (degree Celsius) maximum cardinal temperature for decomposition
746
+ moisture_response_function_at_wilting_point: (mm3/mm3) soil volumetric water content at reference wilting point
747
+ moisture_response_function_at_saturation: (mm3/mm3) soil volumetric water content at reference saturation
748
+ evapotranspirations: (mm/d) all-year daily values of reference crop evapotranspiration
749
+ precipitations: (mm/d) all-year daily values of precipitation
750
+ temperatures: (mm/d) all-year daily values of air temperature
751
+
752
+ Returns:
753
+ values of the climate parameter for all days of the year.
754
+
755
+ Holos source code:
756
+ https://github.com/holos-aafc/Holos/blob/8a3d8fb047c2058a3dbe273f5a8550ae63a54f14/H.Core/Calculators/Climate/ClimateParameterCalculator.cs#L112
757
+ """
758
+ green_area_index_max = calculate_green_area_index_max(
759
+ crop_yield=crop_yield)
760
+
761
+ mid_season = calculate_mid_season(
762
+ emergence_day=emergence_day,
763
+ ripening_day=ripening_day)
764
+
765
+ organic_carbon_factor = calculate_organic_carbon_factor(
766
+ percent_organic_carbon=percentage_soil_organic_carbon)
767
+
768
+ clay_factor = calculate_clay_factor(clay_content=clay)
769
+ sand_factor = calculate_sand_factor(sand_content=sand)
770
+
771
+ wilting_point = calculate_wilting_point(
772
+ organic_carbon_factor=organic_carbon_factor,
773
+ clay_factor=clay_factor,
774
+ sand_factor=sand_factor)
775
+
776
+ field_capacity = calculate_field_capacity(
777
+ organic_carbon_factor=organic_carbon_factor,
778
+ clay_factor=clay_factor,
779
+ sand_factor=sand_factor)
780
+
781
+ soil_mean_depth = calculate_soil_mean_depth(
782
+ layer_thickness=layer_thickness_in_millimeters)
783
+
784
+ soil_temperature_previous = 0
785
+ soil_water_storage_previous = field_capacity * layer_thickness_in_millimeters
786
+
787
+ daily_climate_parameter_list = []
788
+
789
+ for julian_day, temperature, precipitation, evapotranspiration in zip(
790
+ _get_julian_days(), temperatures, precipitations, evapotranspirations):
791
+ daily_climate_parameter = calculate_daily_climate_parameter(
792
+ julian_day=julian_day,
793
+ mid_season=mid_season,
794
+ temperature=temperature,
795
+ precipitation=precipitation,
796
+ evapotranspiration=evapotranspiration,
797
+ variance=variance,
798
+ field_capacity=field_capacity,
799
+ wilting_point=wilting_point,
800
+ layer_thickness=layer_thickness_in_millimeters,
801
+ soil_mean_depth=soil_mean_depth,
802
+ green_area_index_max=green_area_index_max,
803
+ alfa=alfa,
804
+ decomposition_minimum_temperature=decomposition_minimum_temperature,
805
+ decomposition_maximum_temperature=decomposition_maximum_temperature,
806
+ moisture_response_function_at_saturation=moisture_response_function_at_saturation,
807
+ moisture_response_function_at_wilting_point=moisture_response_function_at_wilting_point,
808
+ soil_temperature_previous=soil_temperature_previous,
809
+ soil_water_storage_previous=soil_water_storage_previous)
810
+
811
+ soil_temperature_previous = daily_climate_parameter.SoilTemperature
812
+ soil_water_storage_previous = daily_climate_parameter.SoilWaterStorage
813
+
814
+ daily_climate_parameter_list.append(daily_climate_parameter.ClimateParameter)
815
+
816
+ return daily_climate_parameter_list
817
+
818
+
819
+ def calculate_climate_parameter(
820
+ emergence_day: int,
821
+ ripening_day: int,
822
+ crop_yield: float,
823
+ clay: float,
824
+ sand: float,
825
+ layer_thickness_in_millimeters: float,
826
+ percentage_soil_organic_carbon: float,
827
+ variance: float,
828
+ alfa: float,
829
+ decomposition_minimum_temperature: float,
830
+ decomposition_maximum_temperature: float,
831
+ moisture_response_function_at_wilting_point: float,
832
+ moisture_response_function_at_saturation: float,
833
+ evapotranspirations: list[float],
834
+ precipitations: list[float],
835
+ temperatures: list[float]
836
+ ) -> float:
837
+ """Calculates all average of all daily values of the climate parameter.
838
+
839
+ Args:
840
+ emergence_day: (julian day) day of plant emergence
841
+ ripening_day: (julian day) day of plant ripening
842
+ crop_yield: (kg(DM)/ha) crop yield
843
+ clay: fraction of clay in soil (between 0 and 1)
844
+ sand: fraction of sand in soil (between 0 and 1)
845
+ layer_thickness_in_millimeters: (mm) soil layer thickness
846
+ percentage_soil_organic_carbon: (%) percentage of organic C in soil (between 0 and 100), by weight
847
+ variance: width of distribution function
848
+ alfa: (-) minimum water storage fraction of wilting_point
849
+ decomposition_minimum_temperature: (degree Celsius) minimum cardinal temperature for decomposition
850
+ decomposition_maximum_temperature: (degree Celsius) maximum cardinal temperature for decomposition
851
+ moisture_response_function_at_wilting_point: (mm3/mm3) soil volumetric water content at reference wilting point
852
+ moisture_response_function_at_saturation: (mm3/mm3) soil volumetric water content at reference saturation
853
+ evapotranspirations: (mm/d) all-year daily values of reference crop evapotranspiration
854
+ precipitations: (mm/d) all-year values of precipitation
855
+ temperatures: (degrees Celsius) all-year values of air temperature
856
+
857
+ Returns:
858
+ average value of the climate parameter of all days of the year.
859
+
860
+ Holos source code:
861
+ https://github.com/holos-aafc/Holos/blob/8a3d8fb047c2058a3dbe273f5a8550ae63a54f14/H.Core/Calculators/Climate/ClimateParameterCalculator.cs#L226C23-L226C48
862
+ """
863
+ return calc_average(values=calculate_daily_climate_parameters(**locals()))