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,2301 @@
|
|
|
1
|
+
from enum import auto
|
|
2
|
+
from typing import ClassVar
|
|
3
|
+
|
|
4
|
+
from pandas import DataFrame
|
|
5
|
+
from pydantic import BaseModel, Field, NonNegativeFloat
|
|
6
|
+
|
|
7
|
+
from pyholos import utils
|
|
8
|
+
from pyholos.common import (ClimateZones, EnumGeneric, HolosVar, Region,
|
|
9
|
+
get_climate_zone, get_region)
|
|
10
|
+
from pyholos.components.common import (
|
|
11
|
+
ComponentCategory,
|
|
12
|
+
calculate_fraction_of_nitrogen_lost_by_leaching_and_runoff)
|
|
13
|
+
from pyholos.config import PathsHolosResources
|
|
14
|
+
from pyholos.defaults import Defaults
|
|
15
|
+
from pyholos.common2 import CanadianProvince
|
|
16
|
+
from pyholos.soil import SoilTexture
|
|
17
|
+
from pyholos.utils import AutoNameEnum, read_holos_resource_table
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class DietAdditiveType(EnumGeneric):
|
|
21
|
+
"""Holos source code: https://github.com/holos-aafc/Holos/blob/396f1ab9bc7247e6d78766f9445c14d2eb7c0d9d/H.Core/Enumerations/DietAdditiveType.cs#L6
|
|
22
|
+
|
|
23
|
+
"""
|
|
24
|
+
two_percent_fat: str = "TwoPercentFat"
|
|
25
|
+
four_percent_fat: str = "FourPercentFat"
|
|
26
|
+
five_percent_fat: str = "FivePercentFat"
|
|
27
|
+
ionophore: str = "Inonophore"
|
|
28
|
+
ionophore_plus_two_percent_fat: str = "InonophorePlusTwoPercentFat"
|
|
29
|
+
ionophore_plus_four_percent_fat: str = "InonophorePlusFourPercentFat"
|
|
30
|
+
ionophore_plus_five_percent_fat: str = "IonophorePlusFivePercentFat"
|
|
31
|
+
custom: str = "Custom"
|
|
32
|
+
NONE: str = "None"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class ProductionStage(EnumGeneric):
|
|
36
|
+
gestating: str = "Gestating"
|
|
37
|
+
"""Animals that are pregnant.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
lactating: str = "Lactating"
|
|
41
|
+
"""Animals that are lactating. Also known as farrowing in swine systems.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
open: str = "Open"
|
|
45
|
+
"""Animals that are neither lactating or pregnant.
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
weaning: str = "Weaning"
|
|
49
|
+
"""Animals that have not been weaned yet.
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
growing_and_finishing: str = "GrowingAndFinishing"
|
|
53
|
+
"""Animals that have not been weaned yet.
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
breeding_stock: str = "BreedingStock"
|
|
57
|
+
"""Animals that are used for breeding (boars, bulls, etc.)
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
weaned: str = "Weaned"
|
|
61
|
+
"""Animals that have been weaned and are no longer milk fed.
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
class AnimalType(EnumGeneric):
|
|
66
|
+
not_selected: str = "NotSelected"
|
|
67
|
+
alpacas: str = "Alpacas"
|
|
68
|
+
beef_backgrounder: str = "BeefBackgrounder"
|
|
69
|
+
beef_backgrounder_steer: str = "BeefBackgrounderSteer"
|
|
70
|
+
beef_backgrounder_heifer: str = "BeefBackgrounderHeifer"
|
|
71
|
+
beef_finishing_steer: str = "BeefFinishingSteer"
|
|
72
|
+
beef_finishing_heifer: str = "BeefFinishingHeifer"
|
|
73
|
+
beef: str = "Beef"
|
|
74
|
+
beef_bulls: str = "BeefBulls"
|
|
75
|
+
beef_calf: str = "BeefCalf"
|
|
76
|
+
beef_cow_lactating: str = "BeefCowLactating" # This also means 'regular' cows (i.e. non-lactating)
|
|
77
|
+
beef_cow_dry: str = "BeefCowDry"
|
|
78
|
+
beef_finisher: str = "BeefFinisher" # /// Also known as buffalo
|
|
79
|
+
bison: str = "Bison"
|
|
80
|
+
swine_boar: str = "SwineBoar"
|
|
81
|
+
broilers: str = "Broilers"
|
|
82
|
+
chicken: str = "Chicken"
|
|
83
|
+
cow_calf: str = "CowCalf"
|
|
84
|
+
beef_cow: str = "BeefCow"
|
|
85
|
+
calf: str = "Calf"
|
|
86
|
+
dairy: str = "Dairy"
|
|
87
|
+
dairy_bulls: str = "DairyBulls"
|
|
88
|
+
dairy_dry_cow: str = "DairyDryCow"
|
|
89
|
+
dairy_calves: str = "DairyCalves"
|
|
90
|
+
dairy_heifers: str = "DairyHeifers"
|
|
91
|
+
dairy_lactating_cow: str = "DairyLactatingCow"
|
|
92
|
+
deer: str = "Deer"
|
|
93
|
+
swine_dry_sow: str = "SwineDrySow"
|
|
94
|
+
ducks: str = "Ducks"
|
|
95
|
+
elk: str = "Elk"
|
|
96
|
+
ewes: str = "Ewes" # Assumption is all ewes are pregnant
|
|
97
|
+
geese: str = "Geese"
|
|
98
|
+
goats: str = "Goats"
|
|
99
|
+
swine_grower: str = "SwineGrower" # Also known as Hogs
|
|
100
|
+
horses: str = "Horses"
|
|
101
|
+
lambs: str = "Lambs"
|
|
102
|
+
lambs_and_ewes: str = "LambsAndEwes"
|
|
103
|
+
swine_lactating_sow: str = "SwineLactatingSow"
|
|
104
|
+
layers_dry_poultry: str = "LayersDryPoultry"
|
|
105
|
+
layers_wet_poultry: str = "LayersWetPoultry"
|
|
106
|
+
llamas: str = "Llamas"
|
|
107
|
+
mules: str = "Mules"
|
|
108
|
+
other_livestock: str = "OtherLivestock"
|
|
109
|
+
poultry: str = "Poultry"
|
|
110
|
+
beef_replacement_heifers: str = "BeefReplacementHeifers"
|
|
111
|
+
sheep: str = "Sheep"
|
|
112
|
+
ram: str = "Ram"
|
|
113
|
+
weaned_lamb: str = "WeanedLamb"
|
|
114
|
+
sheep_feedlot: str = "SheepFeedlot"
|
|
115
|
+
stockers: str = "Stockers"
|
|
116
|
+
stocker_steers: str = "StockerSteers"
|
|
117
|
+
stocker_heifers: str = "StockerHeifers"
|
|
118
|
+
swine: str = "Swine"
|
|
119
|
+
swine_starter: str = "SwineStarter"
|
|
120
|
+
swine_finisher: str = "SwineFinisher"
|
|
121
|
+
turkeys: str = "Turkeys"
|
|
122
|
+
young_bulls: str = "YoungBulls"
|
|
123
|
+
swine_gilts: str = "SwineGilts" # Female pigs that have not farrowed a litter. Also known as maiden gilts.
|
|
124
|
+
swine_sows: str = "SwineSows"
|
|
125
|
+
swine_piglets: str = "SwinePiglets"
|
|
126
|
+
chicken_pullets: str = "ChickenPullets" # Juvenile female
|
|
127
|
+
chicken_cockerels: str = "ChickenCockerels" # Juvenile male
|
|
128
|
+
chicken_roosters: str = "ChickenRoosters" # Adult male
|
|
129
|
+
chicken_hens: str = "ChickenHens" # Adult female
|
|
130
|
+
young_tom: str = "YoungTom" # Juvenile male turkey
|
|
131
|
+
tom: str = "Tom" # Adult male turkey
|
|
132
|
+
young_turkey_hen: str = "YoungTurkeyHen" # Young female turkey
|
|
133
|
+
turkey_hen: str = "TurkeyHen" # Adult female turkey
|
|
134
|
+
chicken_eggs: str = "ChickenEggs"
|
|
135
|
+
turkey_eggs: str = "TurkeyEggs"
|
|
136
|
+
chicks: str = "Chicks" # Newly hatched chicken
|
|
137
|
+
poults: str = "Poults" # Newly hatched turkey
|
|
138
|
+
cattle: str = "Cattle"
|
|
139
|
+
layers: str = "Layers"
|
|
140
|
+
|
|
141
|
+
def is_young_type(self):
|
|
142
|
+
return self in {
|
|
143
|
+
self.__class__.beef_calf,
|
|
144
|
+
self.__class__.dairy_calves,
|
|
145
|
+
self.__class__.swine_piglets,
|
|
146
|
+
self.__class__.weaned_lamb,
|
|
147
|
+
self.__class__.lambs
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
def is_beef_cattle_type(self):
|
|
151
|
+
return self in {
|
|
152
|
+
self.__class__.beef,
|
|
153
|
+
self.__class__.beef_backgrounder,
|
|
154
|
+
self.__class__.beef_bulls,
|
|
155
|
+
self.__class__.beef_backgrounder_heifer,
|
|
156
|
+
self.__class__.beef_finishing_steer,
|
|
157
|
+
self.__class__.beef_finishing_heifer,
|
|
158
|
+
self.__class__.beef_replacement_heifers,
|
|
159
|
+
self.__class__.beef_finisher,
|
|
160
|
+
self.__class__.beef_backgrounder_steer,
|
|
161
|
+
self.__class__.beef_calf,
|
|
162
|
+
self.__class__.stockers,
|
|
163
|
+
self.__class__.stocker_heifers,
|
|
164
|
+
self.__class__.stocker_steers,
|
|
165
|
+
self.__class__.beef_cow_lactating,
|
|
166
|
+
self.__class__.beef_cow,
|
|
167
|
+
self.__class__.beef_cow_dry
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
def is_dairy_cattle_type(self):
|
|
171
|
+
return self in {
|
|
172
|
+
self.__class__.dairy,
|
|
173
|
+
self.__class__.dairy_lactating_cow,
|
|
174
|
+
self.__class__.dairy_bulls,
|
|
175
|
+
self.__class__.dairy_calves,
|
|
176
|
+
self.__class__.dairy_dry_cow,
|
|
177
|
+
self.__class__.dairy_heifers
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
def is_swine_type(self):
|
|
181
|
+
return self in {
|
|
182
|
+
self.__class__.swine,
|
|
183
|
+
self.__class__.swine_finisher,
|
|
184
|
+
self.__class__.swine_starter,
|
|
185
|
+
self.__class__.swine_lactating_sow,
|
|
186
|
+
self.__class__.swine_dry_sow,
|
|
187
|
+
self.__class__.swine_grower,
|
|
188
|
+
self.__class__.swine_sows,
|
|
189
|
+
self.__class__.swine_boar,
|
|
190
|
+
self.__class__.swine_gilts,
|
|
191
|
+
self.__class__.swine_piglets
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
def is_sheep_type(self):
|
|
195
|
+
return self in {
|
|
196
|
+
self.__class__.sheep,
|
|
197
|
+
self.__class__.lambs_and_ewes,
|
|
198
|
+
self.__class__.ram,
|
|
199
|
+
self.__class__.weaned_lamb,
|
|
200
|
+
self.__class__.lambs,
|
|
201
|
+
self.__class__.ewes,
|
|
202
|
+
self.__class__.sheep_feedlot
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
def is_poultry_type(self):
|
|
206
|
+
return self in {
|
|
207
|
+
self.__class__.poultry,
|
|
208
|
+
self.__class__.layers_wet_poultry,
|
|
209
|
+
self.__class__.layers_dry_poultry,
|
|
210
|
+
self.__class__.layers,
|
|
211
|
+
self.__class__.broilers,
|
|
212
|
+
self.__class__.turkeys,
|
|
213
|
+
self.__class__.ducks,
|
|
214
|
+
self.__class__.geese,
|
|
215
|
+
self.__class__.chicken_pullets,
|
|
216
|
+
self.__class__.chicken_cockerels,
|
|
217
|
+
self.__class__.chicken_roosters,
|
|
218
|
+
self.__class__.chicken_hens,
|
|
219
|
+
self.__class__.young_tom,
|
|
220
|
+
self.__class__.tom,
|
|
221
|
+
self.__class__.young_turkey_hen,
|
|
222
|
+
self.__class__.turkey_hen,
|
|
223
|
+
self.__class__.chicken_eggs,
|
|
224
|
+
self.__class__.turkey_eggs,
|
|
225
|
+
self.__class__.chicks,
|
|
226
|
+
self.__class__.poults
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
def is_other_animal_type(self):
|
|
230
|
+
return self in {
|
|
231
|
+
self.__class__.other_livestock,
|
|
232
|
+
self.__class__.goats,
|
|
233
|
+
self.__class__.alpacas,
|
|
234
|
+
self.__class__.deer,
|
|
235
|
+
self.__class__.elk,
|
|
236
|
+
self.__class__.llamas,
|
|
237
|
+
self.__class__.horses,
|
|
238
|
+
self.__class__.mules,
|
|
239
|
+
self.__class__.bison
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
def is_chicken_type(self):
|
|
243
|
+
return self in {
|
|
244
|
+
self.__class__.chicken,
|
|
245
|
+
self.__class__.chicken_hens,
|
|
246
|
+
self.__class__.layers,
|
|
247
|
+
self.__class__.broilers,
|
|
248
|
+
self.__class__.chicken_roosters,
|
|
249
|
+
self.__class__.chicken_pullets,
|
|
250
|
+
self.__class__.chicken_cockerels,
|
|
251
|
+
self.__class__.chicken_eggs,
|
|
252
|
+
self.__class__.chicks
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
def is_turkey_type(self):
|
|
256
|
+
return self in {
|
|
257
|
+
self.__class__.turkey_hen,
|
|
258
|
+
self.__class__.young_turkey_hen,
|
|
259
|
+
self.__class__.tom,
|
|
260
|
+
self.__class__.turkey_eggs,
|
|
261
|
+
self.__class__.young_tom,
|
|
262
|
+
self.__class__.poults
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
def is_layers_type(self):
|
|
266
|
+
return self in {
|
|
267
|
+
self.__class__.layers,
|
|
268
|
+
self.__class__.layers_dry_poultry,
|
|
269
|
+
self.__class__.layers_wet_poultry
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
def is_lactating_type(self):
|
|
273
|
+
return self in {
|
|
274
|
+
self.__class__.beef_cow_lactating,
|
|
275
|
+
self.__class__.beef_cow,
|
|
276
|
+
self.__class__.dairy_lactating_cow,
|
|
277
|
+
self.__class__.ewes
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
def is_eggs(self):
|
|
281
|
+
return self in {
|
|
282
|
+
self.__class__.chicken_eggs,
|
|
283
|
+
self.__class__.turkey_eggs
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
def is_newly_hatched_eggs(self):
|
|
287
|
+
return self in {
|
|
288
|
+
self.__class__.poults,
|
|
289
|
+
self.__class__.chicks
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
def is_pregnant_type(self):
|
|
293
|
+
return self in {
|
|
294
|
+
self.__class__.beef_cow,
|
|
295
|
+
self.__class__.beef_cow_lactating,
|
|
296
|
+
self.__class__.dairy_lactating_cow,
|
|
297
|
+
self.__class__.dairy_dry_cow,
|
|
298
|
+
self.__class__.ewes
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
def get_category(self):
|
|
302
|
+
if self.is_other_animal_type():
|
|
303
|
+
res = self.other_livestock
|
|
304
|
+
|
|
305
|
+
elif self.is_poultry_type():
|
|
306
|
+
res = self.poultry
|
|
307
|
+
|
|
308
|
+
elif self.is_sheep_type():
|
|
309
|
+
res = self.sheep
|
|
310
|
+
|
|
311
|
+
elif self.is_swine_type():
|
|
312
|
+
res = self.swine
|
|
313
|
+
|
|
314
|
+
elif self.is_dairy_cattle_type():
|
|
315
|
+
res = self.dairy
|
|
316
|
+
|
|
317
|
+
elif self.is_beef_cattle_type():
|
|
318
|
+
res = self.beef
|
|
319
|
+
|
|
320
|
+
else:
|
|
321
|
+
res = self.not_selected
|
|
322
|
+
|
|
323
|
+
return res
|
|
324
|
+
|
|
325
|
+
def get_component_category_from_animal_type(self):
|
|
326
|
+
if self.is_beef_cattle_type():
|
|
327
|
+
res = ComponentCategory.BeefProduction
|
|
328
|
+
elif self.is_dairy_cattle_type():
|
|
329
|
+
res = ComponentCategory.Dairy
|
|
330
|
+
elif self.is_swine_type():
|
|
331
|
+
res = ComponentCategory.Swine
|
|
332
|
+
elif self.is_poultry_type():
|
|
333
|
+
res = ComponentCategory.Poultry
|
|
334
|
+
elif self.is_sheep_type():
|
|
335
|
+
res = ComponentCategory.Sheep
|
|
336
|
+
else:
|
|
337
|
+
res = ComponentCategory.OtherLivestock
|
|
338
|
+
|
|
339
|
+
return res
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
def convert_animal_type_name(name: str) -> AnimalType:
|
|
343
|
+
"""Maps animal type name to its nearest AnimalType Enum.
|
|
344
|
+
|
|
345
|
+
Holos source code:
|
|
346
|
+
https://github.com/RamiALBASHA/Holos/blob/71638efd97c84c6ded45e342ce664477df6f803f/H.Core/Converters/AnimalTypeStringConverter.cs#L10
|
|
347
|
+
|
|
348
|
+
Notes:
|
|
349
|
+
lines followed by multiple '#' were modified from the original code
|
|
350
|
+
"""
|
|
351
|
+
cleaned_input = name.lower().strip().replace(' ', '').replace('-', '')
|
|
352
|
+
|
|
353
|
+
match cleaned_input:
|
|
354
|
+
# Beef cattle
|
|
355
|
+
case "backgrounding" | "backgrounder":
|
|
356
|
+
return AnimalType.beef_backgrounder
|
|
357
|
+
case "backgroundingsteers":
|
|
358
|
+
return AnimalType.beef_backgrounder_steer
|
|
359
|
+
case "backgroundingheifers":
|
|
360
|
+
return AnimalType.beef_backgrounder_heifer
|
|
361
|
+
case "beef" | "nondairycattle" | "beefcattle":
|
|
362
|
+
return AnimalType.beef
|
|
363
|
+
case "beeffinisher" | "finisher":
|
|
364
|
+
return AnimalType.beef_finisher
|
|
365
|
+
case "cowcalf":
|
|
366
|
+
return AnimalType.cow_calf
|
|
367
|
+
case "stockers":
|
|
368
|
+
return AnimalType.stockers
|
|
369
|
+
case "beefcalves" | "beefcalf":
|
|
370
|
+
return AnimalType.beef_calf
|
|
371
|
+
|
|
372
|
+
# Dairy
|
|
373
|
+
case "dairy" | "dairycattle":
|
|
374
|
+
return AnimalType.dairy
|
|
375
|
+
case "dairybulls":
|
|
376
|
+
return AnimalType.dairy_bulls
|
|
377
|
+
case "dairydry" | "dairydrycow":
|
|
378
|
+
return AnimalType.dairy_dry_cow
|
|
379
|
+
case "dairyheifers":
|
|
380
|
+
return AnimalType.dairy_heifers
|
|
381
|
+
case "dairylactating":
|
|
382
|
+
return AnimalType.dairy_lactating_cow
|
|
383
|
+
|
|
384
|
+
# Swine
|
|
385
|
+
case "boar" | "swineboar":
|
|
386
|
+
return AnimalType.swine_boar
|
|
387
|
+
case "weaners" | "piglets":
|
|
388
|
+
return AnimalType.swine_piglets
|
|
389
|
+
case "drysow":
|
|
390
|
+
return AnimalType.swine_dry_sow
|
|
391
|
+
case "sow" | "sows":
|
|
392
|
+
return AnimalType.swine_sows
|
|
393
|
+
case "grower" | "hogs" | "swinegrower":
|
|
394
|
+
return AnimalType.swine_grower
|
|
395
|
+
case "lactatingsow":
|
|
396
|
+
return AnimalType.swine_lactating_sow
|
|
397
|
+
case "swine":
|
|
398
|
+
return AnimalType.swine
|
|
399
|
+
case "swinefinisher":
|
|
400
|
+
return AnimalType.swine_finisher
|
|
401
|
+
|
|
402
|
+
# Sheep
|
|
403
|
+
case "sheepfeedlot":
|
|
404
|
+
return AnimalType.sheep_feedlot
|
|
405
|
+
case "ewe" | "ewes":
|
|
406
|
+
return AnimalType.ewes
|
|
407
|
+
case "ram" | "rams": ###################
|
|
408
|
+
return AnimalType.ram
|
|
409
|
+
case "sheep" | "sheepandlambs":
|
|
410
|
+
return AnimalType.sheep
|
|
411
|
+
case "weanedlambs" | "lambs": ####################
|
|
412
|
+
return AnimalType.lambs
|
|
413
|
+
|
|
414
|
+
# Other livestock
|
|
415
|
+
case "horse" | "horses":
|
|
416
|
+
return AnimalType.horses
|
|
417
|
+
case "goat" | "goats":
|
|
418
|
+
return AnimalType.goats
|
|
419
|
+
case "mules" | "mule":
|
|
420
|
+
return AnimalType.mules
|
|
421
|
+
case "bull":
|
|
422
|
+
return AnimalType.beef_bulls
|
|
423
|
+
case "llamas":
|
|
424
|
+
return AnimalType.llamas
|
|
425
|
+
case "alpacas":
|
|
426
|
+
return AnimalType.alpacas
|
|
427
|
+
case "deer":
|
|
428
|
+
return AnimalType.deer
|
|
429
|
+
case "elk":
|
|
430
|
+
return AnimalType.elk
|
|
431
|
+
case "bison":
|
|
432
|
+
return AnimalType.bison
|
|
433
|
+
|
|
434
|
+
# Poultry
|
|
435
|
+
case "poultry":
|
|
436
|
+
return AnimalType.poultry
|
|
437
|
+
case "poultrypulletsbroilers" | "chickenbroilers" | "broilers":
|
|
438
|
+
return AnimalType.broilers
|
|
439
|
+
case "chickenpullets" | "pullets":
|
|
440
|
+
return AnimalType.chicken_pullets
|
|
441
|
+
case "chicken":
|
|
442
|
+
return AnimalType.chicken
|
|
443
|
+
case "chickencockerels" | "cockerels":
|
|
444
|
+
return AnimalType.chicken_cockerels
|
|
445
|
+
case "roasters" | "roosters" | "chickenroosters": ####################
|
|
446
|
+
return AnimalType.chicken_roosters
|
|
447
|
+
case "hens":
|
|
448
|
+
return AnimalType.chicken_hens
|
|
449
|
+
case "poultryturkeys" | "turkey" | "ducks":
|
|
450
|
+
return AnimalType.ducks
|
|
451
|
+
case "geese":
|
|
452
|
+
return AnimalType.geese
|
|
453
|
+
case "turkeys":
|
|
454
|
+
return AnimalType.turkeys
|
|
455
|
+
case "layersdry" | "layersdrypoultry": ################
|
|
456
|
+
return AnimalType.layers_dry_poultry
|
|
457
|
+
case "layerswet" | "layerswetpoultry": ################
|
|
458
|
+
return AnimalType.layers_wet_poultry
|
|
459
|
+
case "poultrylayers" | "chickenlayers" | "layers":
|
|
460
|
+
return AnimalType.layers
|
|
461
|
+
case _:
|
|
462
|
+
# raise ValueError(f"unknown animal type. Returning {AnimalType.beef_backgrounder}")
|
|
463
|
+
return AnimalType.beef_backgrounder
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
class ManureAnimalSourceTypes(AutoNameEnum):
|
|
467
|
+
"""
|
|
468
|
+
Holos source type:
|
|
469
|
+
https://github.com/holos-aafc/Holos/blob/c06f6619907fba89c3ddc29b4239a903a8c20a7a/H.Core/Enumerations/ManureAnimalSourceTypes.cs#L9
|
|
470
|
+
"""
|
|
471
|
+
NotSelected = auto()
|
|
472
|
+
BeefManure = auto()
|
|
473
|
+
DairyManure = auto()
|
|
474
|
+
SwineManure = auto()
|
|
475
|
+
PoultryManure = auto()
|
|
476
|
+
SheepManure = auto()
|
|
477
|
+
OtherLivestockManure = auto()
|
|
478
|
+
|
|
479
|
+
|
|
480
|
+
class ManureLocationSourceType(AutoNameEnum):
|
|
481
|
+
NotSelected = auto()
|
|
482
|
+
Livestock = auto()
|
|
483
|
+
Imported = auto()
|
|
484
|
+
OnFarmAnaerobicDigestor = auto()
|
|
485
|
+
|
|
486
|
+
|
|
487
|
+
class Milk(BaseModel):
|
|
488
|
+
"""Milk production data
|
|
489
|
+
|
|
490
|
+
Args:
|
|
491
|
+
production: (kg) average milk production value based on the province and year specified by user
|
|
492
|
+
fat_content: (%) fat content of milk
|
|
493
|
+
protein_content_as_percentage: (%) protein content of milk
|
|
494
|
+
|
|
495
|
+
Notes:
|
|
496
|
+
arg 'protein_content_as_percentage' is deprecated and will be removed in future version.
|
|
497
|
+
"""
|
|
498
|
+
production: float = 0
|
|
499
|
+
fat_content: float = 4
|
|
500
|
+
protein_content_as_percentage: float = 3.5
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
class Diet(BaseModel):
|
|
504
|
+
specs: ClassVar = Field(NonNegativeFloat, ge=0, le=100)
|
|
505
|
+
"""Diet composition data
|
|
506
|
+
|
|
507
|
+
Args:
|
|
508
|
+
crude_protein_percentage: (-) percentage of crude protein in the diet dry matter (between 0 and 100)
|
|
509
|
+
forage_percentage: (-) percentage of forage in the diet dry matter (between 0 and 100)
|
|
510
|
+
total_digestible_nutrient_percentage: (-) percentage of total digestible nutrient in the diet dry matter (between 0 and 100)
|
|
511
|
+
ash_percentage: (-) percentage of ash in the diet dry matter (between 0 and 100)
|
|
512
|
+
starch_percentage: (-) percentage of starch in the diet dry matter (between 0 and 100)
|
|
513
|
+
fat_percentage: (-) percentage of fat in the diet dry matter (between 0 and 100)
|
|
514
|
+
neutral_detergent_fiber_percentage: (-) percentage of neutral detergent fiber in the diet dry matter (between 0 and 100)
|
|
515
|
+
metabolizable_energy: (Mcal kg-1) metabolizable energy of the diet
|
|
516
|
+
"""
|
|
517
|
+
crude_protein_percentage: NonNegativeFloat
|
|
518
|
+
forage_percentage: NonNegativeFloat
|
|
519
|
+
total_digestible_nutrient_percentage: NonNegativeFloat
|
|
520
|
+
ash_percentage: NonNegativeFloat
|
|
521
|
+
starch_percentage: NonNegativeFloat
|
|
522
|
+
fat_percentage: NonNegativeFloat
|
|
523
|
+
neutral_detergent_fiber_percentage: NonNegativeFloat
|
|
524
|
+
metabolizable_energy: NonNegativeFloat
|
|
525
|
+
|
|
526
|
+
# dietary_net_energy_concentration: float
|
|
527
|
+
|
|
528
|
+
@staticmethod
|
|
529
|
+
def calc_dietary_net_energy_concentration(
|
|
530
|
+
net_energy_for_maintenance: float,
|
|
531
|
+
net_energy_for_growth: float
|
|
532
|
+
) -> float:
|
|
533
|
+
"""Calculates the dietary net energy concentration
|
|
534
|
+
|
|
535
|
+
Args:
|
|
536
|
+
net_energy_for_maintenance: (Mcal/kg DM) net energy for maintenance
|
|
537
|
+
net_energy_for_growth: (Mcal/kg DM) net energy for growth
|
|
538
|
+
|
|
539
|
+
Returns:
|
|
540
|
+
(MJ/kg DM): dietary net energy concentration
|
|
541
|
+
|
|
542
|
+
Notes:
|
|
543
|
+
NEmf (MJ/kg DM) = [NEma (Mcal/kg DM) + NEga (Mcal/kg DM)] * 4.184 (conversion factor for Mcal to MJ)
|
|
544
|
+
|
|
545
|
+
References:
|
|
546
|
+
Holos source code https://github.com/holos-aafc/Holos/blob/396f1ab9bc7247e6d78766f9445c14d2eb7c0d9d/H.Core/Providers/Feed/FeedIngredient.cs#L1319
|
|
547
|
+
|
|
548
|
+
"""
|
|
549
|
+
return (net_energy_for_maintenance + net_energy_for_growth) * 4.184
|
|
550
|
+
|
|
551
|
+
def calc_dietary_net_energy_concentration_for_beef(self) -> float:
|
|
552
|
+
"""Calculates the dietary net energy concentration of a beef cattle diet as a function of the metabolizable energy.
|
|
553
|
+
|
|
554
|
+
Returns:
|
|
555
|
+
(MJ (kg DM)^-1) dietary net energy concentration
|
|
556
|
+
|
|
557
|
+
Notes:
|
|
558
|
+
This relationship is deduced from the dairy cattle feed composition table provided in the Holos source code
|
|
559
|
+
'https://github.com/holos-aafc/Holos/blob/main/H.Content/Resources/dairy_feed_composition.csv
|
|
560
|
+
|
|
561
|
+
"""
|
|
562
|
+
return self.calc_dietary_net_energy_concentration(
|
|
563
|
+
net_energy_for_maintenance=self.metabolizable_energy * 0.8756 - 0.5972,
|
|
564
|
+
net_energy_for_growth=self.metabolizable_energy * 0.7632 - 0.9276)
|
|
565
|
+
|
|
566
|
+
def calc_dietary_net_energy_concentration_for_dairy(self) -> float:
|
|
567
|
+
"""Calculates the dietary net energy concentration of a dairy cattle diet as a function of the metabolizable energy.
|
|
568
|
+
|
|
569
|
+
Returns:
|
|
570
|
+
(MJ (kg DM)^-1) dietary net energy concentration
|
|
571
|
+
|
|
572
|
+
Notes:
|
|
573
|
+
This relationship is deduced from the feed composition table provided in the Holos source code
|
|
574
|
+
https://github.com/holos-aafc/Holos/blob/main/H.Content/Resources/feeds.csv
|
|
575
|
+
|
|
576
|
+
"""
|
|
577
|
+
return self.calc_dietary_net_energy_concentration(
|
|
578
|
+
net_energy_for_maintenance=self.metabolizable_energy * 0.8134 - 0.3518,
|
|
579
|
+
net_energy_for_growth=self.metabolizable_energy * 0.6299 - 0.5162)
|
|
580
|
+
|
|
581
|
+
def calc_methane_conversion_factor_for_beef_and_dairy_cattle(
|
|
582
|
+
self,
|
|
583
|
+
animal_type: AnimalType
|
|
584
|
+
) -> float:
|
|
585
|
+
"""Calculates the methane conversion factor based on the animal type.
|
|
586
|
+
|
|
587
|
+
Args:
|
|
588
|
+
animal_type: AnimalType class instance
|
|
589
|
+
|
|
590
|
+
Returns:
|
|
591
|
+
(kg CH4 kg CH4-1) methane conversion factor for diet (Y_m)
|
|
592
|
+
|
|
593
|
+
Holos Source Code:
|
|
594
|
+
https://github.com/holos-aafc/Holos/blob/2bc9704a51449a8ffd4005462a6a7e6fb8a27f2d/H.Core/Providers/Feed/Diet.cs#L602
|
|
595
|
+
"""
|
|
596
|
+
# Assign a default ym so that if there are no cases that cover the diet below, there will be a value assigned
|
|
597
|
+
result = 0.4
|
|
598
|
+
total_digestible_nutrient = self.total_digestible_nutrient_percentage
|
|
599
|
+
|
|
600
|
+
if animal_type.is_dairy_cattle_type():
|
|
601
|
+
if total_digestible_nutrient >= 65:
|
|
602
|
+
result = 0.063
|
|
603
|
+
elif 55 <= total_digestible_nutrient < 65:
|
|
604
|
+
result = 0.065
|
|
605
|
+
else:
|
|
606
|
+
result = 0.07
|
|
607
|
+
|
|
608
|
+
if animal_type.is_beef_cattle_type():
|
|
609
|
+
if total_digestible_nutrient >= 65:
|
|
610
|
+
result = 0.065
|
|
611
|
+
elif 55 <= total_digestible_nutrient < 65:
|
|
612
|
+
result = 0.07
|
|
613
|
+
else:
|
|
614
|
+
result = 0.08
|
|
615
|
+
|
|
616
|
+
if animal_type == AnimalType.beef_finisher:
|
|
617
|
+
if total_digestible_nutrient >= 82:
|
|
618
|
+
result = 0.03
|
|
619
|
+
else:
|
|
620
|
+
result = 0.04
|
|
621
|
+
# The percentage threshold value of 82 is the rounded value of TDN for the basic diet CornGrainBasedDiet.
|
|
622
|
+
# This TDN value is the weighted average of the TDN values of all three ingredients of this diet, i.e.
|
|
623
|
+
# BarleySilage (% TDN = 60.6, % DM in diet=10) and BarleyGrain (% TDN = 84.1, % DM in diet=90)
|
|
624
|
+
# The original code for this part of the function in commented below.
|
|
625
|
+
# if (string.IsNullOrWhiteSpace(this.Name) == false)
|
|
626
|
+
# {
|
|
627
|
+
# if (this.Name.Equals(Resources.LabelCornGrainBasedDiet))
|
|
628
|
+
# {
|
|
629
|
+
# result = 0.03;
|
|
630
|
+
# }
|
|
631
|
+
#
|
|
632
|
+
# if (this.Name.Equals(Resources.LabelBarleyGrainBasedDiet))
|
|
633
|
+
# {
|
|
634
|
+
# result = 0.04;
|
|
635
|
+
#
|
|
636
|
+
# }
|
|
637
|
+
# }
|
|
638
|
+
|
|
639
|
+
return result
|
|
640
|
+
|
|
641
|
+
@staticmethod
|
|
642
|
+
def calc_methane_conversion_factor_for_sheep() -> float:
|
|
643
|
+
"""Returns the methane conversion factor for sheep irrespective of feed quality values
|
|
644
|
+
|
|
645
|
+
Returns:
|
|
646
|
+
(kg CH4 kg CH4-1) methane conversion factor for diet (Y_m)
|
|
647
|
+
|
|
648
|
+
Holos Source Code:
|
|
649
|
+
https://github.com/holos-aafc/Holos/blob/2bc9704a51449a8ffd4005462a6a7e6fb8a27f2d/H.Content/Resources/Table_18_26_Diet_Coefficients_For_Beef_Dairy_Sheep.csv#L33
|
|
650
|
+
|
|
651
|
+
"""
|
|
652
|
+
return 0.067
|
|
653
|
+
|
|
654
|
+
def calc_methane_conversion_factor(
|
|
655
|
+
self,
|
|
656
|
+
animal_type: AnimalType
|
|
657
|
+
) -> float:
|
|
658
|
+
"""Calculates the methane conversion factor based on the animal type.
|
|
659
|
+
|
|
660
|
+
Args:
|
|
661
|
+
animal_type: AnimalType class instance
|
|
662
|
+
|
|
663
|
+
Returns:
|
|
664
|
+
(kg CH4 kg CH4-1) methane conversion factor for diet (Y_m)
|
|
665
|
+
"""
|
|
666
|
+
if animal_type.is_beef_cattle_type() or animal_type.is_dairy_cattle_type():
|
|
667
|
+
res = self.calc_methane_conversion_factor_for_beef_and_dairy_cattle(animal_type=animal_type)
|
|
668
|
+
elif animal_type.is_sheep_type():
|
|
669
|
+
res = self.calc_methane_conversion_factor_for_sheep()
|
|
670
|
+
else:
|
|
671
|
+
res = None
|
|
672
|
+
|
|
673
|
+
return res
|
|
674
|
+
|
|
675
|
+
|
|
676
|
+
class HousingType(EnumGeneric):
|
|
677
|
+
not_selected: str = "NotSelected"
|
|
678
|
+
confined_no_barn: str = "ConfinedNoBarn"
|
|
679
|
+
"""Also known as 'Confined no barn (feedlot)'
|
|
680
|
+
"""
|
|
681
|
+
housed_in_barn: str = "HousedInBarn"
|
|
682
|
+
housed_ewes: str = "HousedEwes"
|
|
683
|
+
housed_in_barn_solid: str = "HousedInBarnSolid"
|
|
684
|
+
housed_in_barn_slurry: str = "HousedInBarnSlurry"
|
|
685
|
+
enclosed_pasture: str = "EnclosedPasture"
|
|
686
|
+
open_range_or_hills: str = "OpenRangeOrHills"
|
|
687
|
+
tie_stall: str = "TieStall"
|
|
688
|
+
small_free_stall: str = "SmallFreeStall"
|
|
689
|
+
large_free_stall: str = "LargeFreeStall"
|
|
690
|
+
grazing_under3km: str = "GrazingUnder3km"
|
|
691
|
+
grazing_over3km: str = "GrazingOver3km"
|
|
692
|
+
confined: str = "Confined"
|
|
693
|
+
flat_pasture: str = "FlatPasture"
|
|
694
|
+
hilly_pasture_or_open_range: str = "HillyPastureOrOpenRange"
|
|
695
|
+
pasture: str = "Pasture"
|
|
696
|
+
"""Pasture, range, or paddock
|
|
697
|
+
"""
|
|
698
|
+
dry_lot: str = "DryLot"
|
|
699
|
+
"""Also known as 'Standing or exercise yard'
|
|
700
|
+
"""
|
|
701
|
+
swath_grazing: str = "SwathGrazing"
|
|
702
|
+
custom: str = "Custom"
|
|
703
|
+
free_stall_barn_solid_litter: str = "FreeStallBarnSolidLitter"
|
|
704
|
+
free_stall_barn_slurry_scraping: str = "FreeStallBarnSlurryScraping"
|
|
705
|
+
free_stall_barn_flushing: str = "FreeStallBarnFlushing"
|
|
706
|
+
free_stall_barn_milk_parlour_slurry_flushing: str = "FreeStallBarnMilkParlourSlurryFlushing"
|
|
707
|
+
"""Also known as 'Milking parlour (slurry - flushing)'
|
|
708
|
+
"""
|
|
709
|
+
tie_stall_solid_litter: str = "TieStallSolidLitter"
|
|
710
|
+
"""Also known as 'Tie-stall barn (solid)'
|
|
711
|
+
"""
|
|
712
|
+
tie_stall_slurry: str = "TieStallSlurry"
|
|
713
|
+
"""Also known as 'Tie-stall barn (slurry)'
|
|
714
|
+
"""
|
|
715
|
+
|
|
716
|
+
# This section corresponds to the HousingTypeExtensions class in the original holos source code
|
|
717
|
+
# https://github.com/holos-aafc/Holos/blob/53f778f9bd4579d164de10f5b04db34d020b96a9/H.Core/Enumerations/HousingTypeExtensions.cs#L10
|
|
718
|
+
|
|
719
|
+
def is_free_stall(self):
|
|
720
|
+
return self in {
|
|
721
|
+
self.__class__.small_free_stall,
|
|
722
|
+
self.__class__.large_free_stall,
|
|
723
|
+
self.__class__.free_stall_barn_flushing,
|
|
724
|
+
self.__class__.free_stall_barn_milk_parlour_slurry_flushing,
|
|
725
|
+
self.__class__.free_stall_barn_slurry_scraping,
|
|
726
|
+
self.__class__.free_stall_barn_solid_litter
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
def is_tie_stall(self):
|
|
730
|
+
return self in {
|
|
731
|
+
self.__class__.tie_stall,
|
|
732
|
+
self.__class__.tie_stall_slurry,
|
|
733
|
+
self.__class__.tie_stall_solid_litter
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
def is_barn(self):
|
|
737
|
+
return self in {
|
|
738
|
+
self.__class__.housed_in_barn,
|
|
739
|
+
self.__class__.housed_in_barn_slurry,
|
|
740
|
+
self.__class__.housed_in_barn_solid
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
def is_feed_lot(self):
|
|
744
|
+
return self in {
|
|
745
|
+
self.__class__.confined,
|
|
746
|
+
self.__class__.confined_no_barn
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
def is_electrical_consuming_housing_type(self):
|
|
750
|
+
return any([
|
|
751
|
+
self.is_free_stall(),
|
|
752
|
+
self.is_barn(),
|
|
753
|
+
self.is_tie_stall(),
|
|
754
|
+
self.is_feed_lot()])
|
|
755
|
+
|
|
756
|
+
def is_indoor_housing(self):
|
|
757
|
+
return self in {
|
|
758
|
+
self.__class__.housed_in_barn,
|
|
759
|
+
self.__class__.housed_in_barn_slurry,
|
|
760
|
+
self.__class__.housed_in_barn_solid,
|
|
761
|
+
self.__class__.free_stall_barn_flushing,
|
|
762
|
+
self.__class__.free_stall_barn_solid_litter,
|
|
763
|
+
self.__class__.free_stall_barn_slurry_scraping,
|
|
764
|
+
self.__class__.free_stall_barn_milk_parlour_slurry_flushing
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
def is_pasture(self):
|
|
768
|
+
return self in {
|
|
769
|
+
self.__class__.pasture,
|
|
770
|
+
self.__class__.enclosed_pasture,
|
|
771
|
+
self.__class__.flat_pasture,
|
|
772
|
+
self.__class__.grazing_over3km,
|
|
773
|
+
self.__class__.grazing_under3km,
|
|
774
|
+
self.__class__.hilly_pasture_or_open_range,
|
|
775
|
+
self.__class__.open_range_or_hills,
|
|
776
|
+
self.__class__.swath_grazing
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
|
|
780
|
+
class BeddingMaterialType(EnumGeneric):
|
|
781
|
+
straw: str = 'Straw'
|
|
782
|
+
wood_chip: str = 'WoodChip'
|
|
783
|
+
separated_manure_solid: str = 'SeparatedManureSolid'
|
|
784
|
+
sand: str = 'Sand'
|
|
785
|
+
straw_long: str = 'StrawLong'
|
|
786
|
+
straw_chopped: str = 'StrawChopped'
|
|
787
|
+
shavings: str = 'Shavings'
|
|
788
|
+
sawdust: str = 'Sawdust'
|
|
789
|
+
paper_products: str = 'PaperProducts'
|
|
790
|
+
peat: str = 'Peat'
|
|
791
|
+
hemp: str = 'Hemp'
|
|
792
|
+
NONE = None
|
|
793
|
+
|
|
794
|
+
|
|
795
|
+
class Bedding:
|
|
796
|
+
def __init__(
|
|
797
|
+
self,
|
|
798
|
+
housing_type: HousingType,
|
|
799
|
+
bedding_material_type: BeddingMaterialType | None,
|
|
800
|
+
animal_type: AnimalType,
|
|
801
|
+
total_carbon_kilograms_dry_matter_for_bedding: float = None,
|
|
802
|
+
total_nitrogen_kilograms_dry_matter_for_bedding: float = None,
|
|
803
|
+
moisture_content_of_bedding_material: float = None
|
|
804
|
+
):
|
|
805
|
+
default_bedding_material_composition = self.get_bedding_material_composition(
|
|
806
|
+
bedding_material_type=bedding_material_type,
|
|
807
|
+
animal_type=animal_type)
|
|
808
|
+
|
|
809
|
+
if total_carbon_kilograms_dry_matter_for_bedding is None:
|
|
810
|
+
total_carbon_kilograms_dry_matter_for_bedding = default_bedding_material_composition[
|
|
811
|
+
'TotalCarbonKilogramsDryMatter']
|
|
812
|
+
if total_nitrogen_kilograms_dry_matter_for_bedding is None:
|
|
813
|
+
total_nitrogen_kilograms_dry_matter_for_bedding = default_bedding_material_composition[
|
|
814
|
+
'TotalNitrogenKilogramsDryMatter']
|
|
815
|
+
if moisture_content_of_bedding_material is None:
|
|
816
|
+
moisture_content_of_bedding_material = default_bedding_material_composition['MoistureContent']
|
|
817
|
+
|
|
818
|
+
self.user_defined_bedding_rate = HolosVar(
|
|
819
|
+
name='User Defined Bedding Rate',
|
|
820
|
+
value=self.get_default_bedding_rate(
|
|
821
|
+
housing_type=housing_type,
|
|
822
|
+
bedding_material_type=bedding_material_type,
|
|
823
|
+
animal_type=animal_type))
|
|
824
|
+
self.total_carbon_kilograms_dry_matter_for_bedding = HolosVar(
|
|
825
|
+
name='Total Carbon Kilograms Dry Matter For Bedding',
|
|
826
|
+
value=total_carbon_kilograms_dry_matter_for_bedding)
|
|
827
|
+
self.total_nitrogen_kilograms_dry_matter_for_bedding = HolosVar(
|
|
828
|
+
name='Total Nitrogen Kilograms Dry Matter For Bedding',
|
|
829
|
+
value=total_nitrogen_kilograms_dry_matter_for_bedding)
|
|
830
|
+
self.moisture_content_of_bedding_material = HolosVar(
|
|
831
|
+
name='Moisture Content Of Bedding Material',
|
|
832
|
+
value=moisture_content_of_bedding_material)
|
|
833
|
+
|
|
834
|
+
@staticmethod
|
|
835
|
+
def get_default_bedding_rate(
|
|
836
|
+
housing_type: HousingType,
|
|
837
|
+
bedding_material_type: BeddingMaterialType,
|
|
838
|
+
animal_type: AnimalType
|
|
839
|
+
) -> int | float:
|
|
840
|
+
# https://github.com/holos-aafc/Holos/blob/53f778f9bd4579d164de10f5b04db34d020b96a9/H.Core/Providers/Animals/Table_30_Default_Bedding_Material_Composition_Provider.cs#L301
|
|
841
|
+
|
|
842
|
+
if housing_type.is_pasture():
|
|
843
|
+
return 0
|
|
844
|
+
|
|
845
|
+
if animal_type.is_young_type():
|
|
846
|
+
return 0
|
|
847
|
+
|
|
848
|
+
if animal_type.is_beef_cattle_type():
|
|
849
|
+
if bedding_material_type == BeddingMaterialType.straw:
|
|
850
|
+
if housing_type.is_feed_lot():
|
|
851
|
+
return 1.5
|
|
852
|
+
|
|
853
|
+
if housing_type.is_barn():
|
|
854
|
+
return 3.5
|
|
855
|
+
|
|
856
|
+
if bedding_material_type == BeddingMaterialType.wood_chip:
|
|
857
|
+
if housing_type.is_feed_lot():
|
|
858
|
+
return 3.6
|
|
859
|
+
|
|
860
|
+
if housing_type.is_barn():
|
|
861
|
+
return 5.0
|
|
862
|
+
|
|
863
|
+
if animal_type.is_dairy_cattle_type():
|
|
864
|
+
# Currently, all housing types have same rates for bedding types
|
|
865
|
+
if any([
|
|
866
|
+
housing_type.is_tie_stall(),
|
|
867
|
+
housing_type.is_free_stall(),
|
|
868
|
+
housing_type == HousingType.dry_lot]):
|
|
869
|
+
if bedding_material_type == BeddingMaterialType.sand:
|
|
870
|
+
return 24.3
|
|
871
|
+
|
|
872
|
+
if bedding_material_type == BeddingMaterialType.separated_manure_solid:
|
|
873
|
+
return 0
|
|
874
|
+
|
|
875
|
+
if bedding_material_type == BeddingMaterialType.straw_long:
|
|
876
|
+
return 0.7
|
|
877
|
+
|
|
878
|
+
if bedding_material_type == BeddingMaterialType.straw_chopped:
|
|
879
|
+
return 0.7
|
|
880
|
+
|
|
881
|
+
if bedding_material_type == BeddingMaterialType.shavings:
|
|
882
|
+
return 2.1
|
|
883
|
+
|
|
884
|
+
if bedding_material_type == BeddingMaterialType.sawdust:
|
|
885
|
+
return 2.1
|
|
886
|
+
|
|
887
|
+
# Footnote 8 for sheep value reference.
|
|
888
|
+
if animal_type.is_sheep_type():
|
|
889
|
+
return 0.57
|
|
890
|
+
|
|
891
|
+
if animal_type.is_swine_type():
|
|
892
|
+
if bedding_material_type == BeddingMaterialType.straw_long:
|
|
893
|
+
return 0.70
|
|
894
|
+
else:
|
|
895
|
+
return 0.79
|
|
896
|
+
|
|
897
|
+
if animal_type.is_poultry_type():
|
|
898
|
+
if any([
|
|
899
|
+
bedding_material_type == BeddingMaterialType.sawdust,
|
|
900
|
+
bedding_material_type == BeddingMaterialType.straw,
|
|
901
|
+
bedding_material_type == BeddingMaterialType.shavings]):
|
|
902
|
+
if animal_type == AnimalType.broilers:
|
|
903
|
+
return 0.0014
|
|
904
|
+
|
|
905
|
+
if animal_type == AnimalType.chicken_pullets:
|
|
906
|
+
return 0.0014
|
|
907
|
+
|
|
908
|
+
if any([
|
|
909
|
+
animal_type == AnimalType.layers,
|
|
910
|
+
animal_type == AnimalType.chicken_hens]):
|
|
911
|
+
return 0.0028
|
|
912
|
+
|
|
913
|
+
if animal_type.is_turkey_type():
|
|
914
|
+
return 0.011
|
|
915
|
+
|
|
916
|
+
else:
|
|
917
|
+
return 0
|
|
918
|
+
else:
|
|
919
|
+
return 0
|
|
920
|
+
|
|
921
|
+
if animal_type.is_other_animal_type():
|
|
922
|
+
# Footnote 11 for Other livestock value reference
|
|
923
|
+
match animal_type:
|
|
924
|
+
case AnimalType.llamas:
|
|
925
|
+
return 0.57
|
|
926
|
+
|
|
927
|
+
case AnimalType.alpacas:
|
|
928
|
+
return 0.57
|
|
929
|
+
|
|
930
|
+
case AnimalType.deer:
|
|
931
|
+
return 1.5
|
|
932
|
+
|
|
933
|
+
case AnimalType.elk:
|
|
934
|
+
return 1.5
|
|
935
|
+
|
|
936
|
+
case AnimalType.goats:
|
|
937
|
+
return 0.57
|
|
938
|
+
|
|
939
|
+
case AnimalType.horses:
|
|
940
|
+
return 1.5
|
|
941
|
+
|
|
942
|
+
case AnimalType.mules:
|
|
943
|
+
return 1.5
|
|
944
|
+
|
|
945
|
+
case AnimalType.bison:
|
|
946
|
+
return 1.5
|
|
947
|
+
|
|
948
|
+
# added here since the original case statement in C# does not cover all possibilities
|
|
949
|
+
case _:
|
|
950
|
+
return 1
|
|
951
|
+
else:
|
|
952
|
+
return 1
|
|
953
|
+
|
|
954
|
+
pass
|
|
955
|
+
|
|
956
|
+
@staticmethod
|
|
957
|
+
def get_bedding_material_composition(
|
|
958
|
+
bedding_material_type: BeddingMaterialType,
|
|
959
|
+
animal_type: AnimalType
|
|
960
|
+
) -> dict:
|
|
961
|
+
if animal_type.is_beef_cattle_type():
|
|
962
|
+
animal_lookup_type = AnimalType.beef
|
|
963
|
+
elif animal_type.is_dairy_cattle_type():
|
|
964
|
+
animal_lookup_type = AnimalType.dairy
|
|
965
|
+
elif animal_type.is_sheep_type():
|
|
966
|
+
animal_lookup_type = AnimalType.sheep
|
|
967
|
+
elif animal_type.is_swine_type():
|
|
968
|
+
animal_lookup_type = AnimalType.swine
|
|
969
|
+
elif animal_type.is_poultry_type():
|
|
970
|
+
animal_lookup_type = AnimalType.poultry
|
|
971
|
+
else:
|
|
972
|
+
# Other animals have a value for animal group (Horses, Goats, etc.)
|
|
973
|
+
animal_lookup_type = animal_type
|
|
974
|
+
|
|
975
|
+
df = HolosTables.Table_30_Default_Bedding_Material_Composition_Provider
|
|
976
|
+
|
|
977
|
+
result = df[
|
|
978
|
+
(df['BeddingMaterial'] == bedding_material_type.value) &
|
|
979
|
+
(df['AnimalType'] == animal_lookup_type.value)]
|
|
980
|
+
|
|
981
|
+
if not result.empty:
|
|
982
|
+
return result.iloc[0].to_dict()
|
|
983
|
+
else:
|
|
984
|
+
# Trace.TraceError($"{nameof(Farm)}.{nameof(GetBeddingMaterialComposition)}: unable to return bedding material data for {animalType.GetDescription()}, and {beddingMaterialType.GetHashCode()}. Returning default value of 1.");
|
|
985
|
+
|
|
986
|
+
# return new Table_30_Default_Bedding_Material_Composition_Data();
|
|
987
|
+
return {k: None for k in result.columns}
|
|
988
|
+
|
|
989
|
+
|
|
990
|
+
class AnimalCoefficientData:
|
|
991
|
+
def __init__(
|
|
992
|
+
self,
|
|
993
|
+
baseline_maintenance_coefficient: float = 0,
|
|
994
|
+
gain_coefficient: float = 0,
|
|
995
|
+
default_initial_weight: float = 0,
|
|
996
|
+
default_final_weight: float = 0
|
|
997
|
+
):
|
|
998
|
+
"""Table 16. Livestock coefficients for beef cattle and dairy cattle.
|
|
999
|
+
|
|
1000
|
+
Args:
|
|
1001
|
+
baseline_maintenance_coefficient: (MJ d-1 kg-1) baseline maintenance coefficient (C_f)
|
|
1002
|
+
gain_coefficient: (dimensionless?) gain coefficient (C_d)
|
|
1003
|
+
default_initial_weight: (kg) initial weight
|
|
1004
|
+
default_final_weight: (kg) final weight
|
|
1005
|
+
"""
|
|
1006
|
+
self.baseline_maintenance_coefficient = baseline_maintenance_coefficient
|
|
1007
|
+
self.gain_coefficient = gain_coefficient
|
|
1008
|
+
self.default_initial_weight = default_initial_weight
|
|
1009
|
+
self.default_final_weight = default_final_weight
|
|
1010
|
+
|
|
1011
|
+
|
|
1012
|
+
def get_methane_producing_capacity_of_manure(
|
|
1013
|
+
animal_type: AnimalType
|
|
1014
|
+
) -> float:
|
|
1015
|
+
"""Returns the default methane producing capacity of manure as a function of the animal type
|
|
1016
|
+
|
|
1017
|
+
Args:
|
|
1018
|
+
animal_type: animal type object
|
|
1019
|
+
|
|
1020
|
+
Returns:
|
|
1021
|
+
(m^3 CH4 kg^-1 VS): Methane producing capacity of manure (B_o)
|
|
1022
|
+
|
|
1023
|
+
References:
|
|
1024
|
+
https://github.com/holos-aafc/Holos/blob/396f1ab9bc7247e6d78766f9445c14d2eb7c0d9d/H.Core/Providers/Animals/Table_35_Methane_Producing_Capacity_Default_Values_Provider.cs#L15
|
|
1025
|
+
|
|
1026
|
+
"""
|
|
1027
|
+
# Table 35. Default values for maximum methane producing capacity (Bo).
|
|
1028
|
+
# <para>Source: IPCC (2019), Table 10.16</para>
|
|
1029
|
+
# Footnote 3 : For Methane producing capacity (B0) value reference.
|
|
1030
|
+
|
|
1031
|
+
if animal_type.is_beef_cattle_type():
|
|
1032
|
+
res = 0.19
|
|
1033
|
+
|
|
1034
|
+
elif animal_type.is_dairy_cattle_type():
|
|
1035
|
+
res = 0.24
|
|
1036
|
+
|
|
1037
|
+
elif animal_type.is_swine_type():
|
|
1038
|
+
res = 0.48
|
|
1039
|
+
|
|
1040
|
+
elif animal_type.is_sheep_type():
|
|
1041
|
+
res = 0.19
|
|
1042
|
+
|
|
1043
|
+
elif any([
|
|
1044
|
+
animal_type == AnimalType.chicken_roosters,
|
|
1045
|
+
animal_type == AnimalType.broilers
|
|
1046
|
+
]):
|
|
1047
|
+
# Used for broilers from algorithm document
|
|
1048
|
+
res = 0.36
|
|
1049
|
+
|
|
1050
|
+
elif any((
|
|
1051
|
+
animal_type == AnimalType.chicken_hens,
|
|
1052
|
+
animal_type == AnimalType.chicken_pullets,
|
|
1053
|
+
animal_type == AnimalType.chicken_cockerels,
|
|
1054
|
+
animal_type == AnimalType.layers
|
|
1055
|
+
)):
|
|
1056
|
+
# Used for layers (wet/dry) from algorithm document
|
|
1057
|
+
res = 0.39
|
|
1058
|
+
|
|
1059
|
+
elif animal_type == AnimalType.goats:
|
|
1060
|
+
res = 0.18
|
|
1061
|
+
|
|
1062
|
+
elif animal_type == AnimalType.horses:
|
|
1063
|
+
res = 0.30
|
|
1064
|
+
|
|
1065
|
+
elif animal_type == AnimalType.mules:
|
|
1066
|
+
res = 0.33
|
|
1067
|
+
|
|
1068
|
+
# Footnote 2
|
|
1069
|
+
elif any((
|
|
1070
|
+
animal_type == AnimalType.llamas,
|
|
1071
|
+
animal_type == AnimalType.alpacas
|
|
1072
|
+
)):
|
|
1073
|
+
res = 0.19
|
|
1074
|
+
|
|
1075
|
+
# Footnote 1
|
|
1076
|
+
elif animal_type == AnimalType.bison:
|
|
1077
|
+
res = 0.10
|
|
1078
|
+
|
|
1079
|
+
else:
|
|
1080
|
+
res = 0
|
|
1081
|
+
|
|
1082
|
+
# Footnote 1: Value for non-dairy cattle used
|
|
1083
|
+
# Footnote 2: Value for sheep used
|
|
1084
|
+
# Footnote 3: For all animals on pasture, range or paddock, the Bo should be set to 0.19
|
|
1085
|
+
|
|
1086
|
+
return res
|
|
1087
|
+
|
|
1088
|
+
|
|
1089
|
+
def get_default_methane_producing_capacity_of_manure(
|
|
1090
|
+
is_pasture: bool,
|
|
1091
|
+
animal_type: AnimalType
|
|
1092
|
+
) -> float:
|
|
1093
|
+
"""Returns the default methane producing capacity of manure.
|
|
1094
|
+
|
|
1095
|
+
Args:
|
|
1096
|
+
is_pasture: True if the housing type is pasture, otherwise False
|
|
1097
|
+
animal_type: animal type class
|
|
1098
|
+
|
|
1099
|
+
Returns:
|
|
1100
|
+
(m^3 CH4 kg^-1 VS): Methane producing capacity of manure (B_o)
|
|
1101
|
+
|
|
1102
|
+
Notes:
|
|
1103
|
+
When housed on pasture, this value should be set to a constant.
|
|
1104
|
+
See table 38 "Default values (in Holos source code) for maximum methane producing capacity (Bo)" footnote 3.
|
|
1105
|
+
|
|
1106
|
+
References:
|
|
1107
|
+
https://github.com/holos-aafc/Holos/blob/396f1ab9bc7247e6d78766f9445c14d2eb7c0d9d/H.Core/Services/Initialization/Animals/AnimalInitializationService.Methane.cs#L89
|
|
1108
|
+
"""
|
|
1109
|
+
return 0.19 if is_pasture else get_methane_producing_capacity_of_manure(animal_type=animal_type)
|
|
1110
|
+
|
|
1111
|
+
|
|
1112
|
+
class FractionOfOrganicNitrogenMineralizedData:
|
|
1113
|
+
def __init__(
|
|
1114
|
+
self,
|
|
1115
|
+
fraction_immobilized: float = 0,
|
|
1116
|
+
fraction_mineralized: float = 0,
|
|
1117
|
+
fraction_nitrified: float = 0,
|
|
1118
|
+
fraction_denitrified: float = 0,
|
|
1119
|
+
n2o_n: float = 0,
|
|
1120
|
+
no_n: float = 0,
|
|
1121
|
+
n2_n: float = 0,
|
|
1122
|
+
n_leached: float = 0,
|
|
1123
|
+
):
|
|
1124
|
+
"""Mineralization of organic N (fecal N and bedding N)
|
|
1125
|
+
|
|
1126
|
+
Args:
|
|
1127
|
+
fraction_mineralized: (dimensionless) fraction of nitrogen mineralized
|
|
1128
|
+
fraction_immobilized: (dimensionless) fraction of nitrogen immobilized
|
|
1129
|
+
fraction_nitrified: (dimensionless) fraction of nitrogen nitrified
|
|
1130
|
+
fraction_denitrified: (dimensionless) fraction of nitrogen denitrified
|
|
1131
|
+
n2o_n:
|
|
1132
|
+
no_n:
|
|
1133
|
+
n2_n:
|
|
1134
|
+
n_leached:
|
|
1135
|
+
"""
|
|
1136
|
+
self.fraction_mineralized = fraction_mineralized
|
|
1137
|
+
self.fraction_immobilized = fraction_immobilized
|
|
1138
|
+
self.fraction_nitrified = fraction_nitrified
|
|
1139
|
+
self.fraction_denitrified = fraction_denitrified
|
|
1140
|
+
self.n2o_n = n2o_n
|
|
1141
|
+
self.no_n = no_n
|
|
1142
|
+
self.n2_n = n2_n
|
|
1143
|
+
self.n_leached = n_leached
|
|
1144
|
+
|
|
1145
|
+
def __eq__(self, other):
|
|
1146
|
+
return self.__dict__ == other.__dict__ if isinstance(other, self.__class__) else False
|
|
1147
|
+
|
|
1148
|
+
|
|
1149
|
+
class ManureStateType(EnumGeneric):
|
|
1150
|
+
not_selected: str = "NotSelected"
|
|
1151
|
+
anaerobic_digester: str = "AnaerobicDigester"
|
|
1152
|
+
composted: str = "Composted"
|
|
1153
|
+
compost_intensive: str = "CompostIntensive" # Also known as 'compost - intensive windrow'
|
|
1154
|
+
compost_passive: str = "CompostPassive" # Also known as 'compost - passive windrow'
|
|
1155
|
+
daily_spread: str = "DailySpread"
|
|
1156
|
+
deep_bedding: str = "DeepBedding"
|
|
1157
|
+
deep_pit: str = "DeepPit" # Also known as 'Deep pit under barn'
|
|
1158
|
+
liquid: str = "Liquid"
|
|
1159
|
+
liquid_crust: str = "LiquidCrust" # [Obsolete]
|
|
1160
|
+
liquid_separated: str = "LiquidSeparated" # [Obsolete]
|
|
1161
|
+
liquid_no_crust: str = "LiquidNoCrust" # Also known as 'Liquid/Slurry with no natural crust'
|
|
1162
|
+
pasture: str = "Pasture"
|
|
1163
|
+
range: str = "Range"
|
|
1164
|
+
paddock: str = "Paddock"
|
|
1165
|
+
solid: str = "Solid"
|
|
1166
|
+
slurry: str = "Slurry" # [Obsolete]
|
|
1167
|
+
slurry_with_natural_crust: str = "SlurryWithNaturalCrust" # [Obsolete]
|
|
1168
|
+
slurry_without_natural_crust: str = "SlurryWithoutNaturalCrust" # [Obsolete]
|
|
1169
|
+
solid_storage: str = "SolidStorage" # Also known as 'Solid storage (stockpiled)'
|
|
1170
|
+
custom: str = "Custom"
|
|
1171
|
+
pit_lagoon_no_cover: str = "PitLagoonNoCover" # [Obsolete]
|
|
1172
|
+
liquid_with_natural_crust: str = "LiquidWithNaturalCrust" # Also known as 'Liquid/Slurry with natural crust'
|
|
1173
|
+
liquid_with_solid_cover: str = "LiquidWithSolidCover" # Also known as Liquid/Slurry with solid cover
|
|
1174
|
+
composted_in_vessel: str = "CompostedInVessel" # (Swine system)
|
|
1175
|
+
solid_storage_with_or_without_litter: str = "SolidStorageWithOrWithoutLitter" # (Poultry system) No different than 'Solid Storage' but poultry solid storage needs the term 'litter' which is incorrect to use in the case of cattle 'Solid Storage' since there is no 'litter' only 'bedding' when considering the cattle system
|
|
1176
|
+
|
|
1177
|
+
# These methods correspond to the ManureStateTypeExtensions
|
|
1178
|
+
# https://github.com/holos-aafc/Holos/blob/396f1ab9bc7247e6d78766f9445c14d2eb7c0d9d/H.Core/Enumerations/ManureStateTypeExtensions.cs#L9
|
|
1179
|
+
def is_grazing_area(self) -> bool:
|
|
1180
|
+
return self in {
|
|
1181
|
+
self.__class__.paddock,
|
|
1182
|
+
self.__class__.range,
|
|
1183
|
+
self.__class__.pasture
|
|
1184
|
+
}
|
|
1185
|
+
|
|
1186
|
+
def is_liquid_manure(self) -> bool:
|
|
1187
|
+
"""Indicates if the storage type being used houses liquid manure.
|
|
1188
|
+
|
|
1189
|
+
Returns:
|
|
1190
|
+
True if the storage type is for liquid manure, False otherwise
|
|
1191
|
+
"""
|
|
1192
|
+
return self in {
|
|
1193
|
+
self.__class__.liquid_no_crust,
|
|
1194
|
+
self.__class__.liquid_with_natural_crust,
|
|
1195
|
+
self.__class__.liquid_with_solid_cover,
|
|
1196
|
+
self.__class__.deep_pit
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
def is_compost(self) -> bool:
|
|
1200
|
+
return self in {
|
|
1201
|
+
self.__class__.compost_intensive,
|
|
1202
|
+
self.__class__.compost_passive,
|
|
1203
|
+
self.__class__.composted
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1206
|
+
def is_solid_manure(self) -> bool:
|
|
1207
|
+
"""Indicates if the storage type being used houses solid manure.
|
|
1208
|
+
|
|
1209
|
+
Returns:
|
|
1210
|
+
True if the storage type is for solid manure, False otherwise
|
|
1211
|
+
"""
|
|
1212
|
+
return not self.is_liquid_manure()
|
|
1213
|
+
|
|
1214
|
+
def is_covered_system(self) -> bool:
|
|
1215
|
+
# Dairy manure systems can be covered with a lid/cap etc.
|
|
1216
|
+
return self in {
|
|
1217
|
+
self.__class__.liquid_with_natural_crust,
|
|
1218
|
+
self.__class__.liquid_with_solid_cover
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1221
|
+
|
|
1222
|
+
def get_fraction_of_organic_nitrogen_mineralized_data(
|
|
1223
|
+
state_type: ManureStateType,
|
|
1224
|
+
animal_type: AnimalType,
|
|
1225
|
+
fraction_of_tan_in_liquid_manure_storage_system: float = 1
|
|
1226
|
+
) -> FractionOfOrganicNitrogenMineralizedData:
|
|
1227
|
+
"""Table 44. Fraction of organic N mineralized as TAN and the fraction of TAN immobilized to organic N and nitrified
|
|
1228
|
+
and denitrified during solid and liquid manure storage for beef and dairy cattle (based on TAN content)
|
|
1229
|
+
(Chai et al., 2014,2016).
|
|
1230
|
+
|
|
1231
|
+
Args:
|
|
1232
|
+
state_type: manure handling system type
|
|
1233
|
+
animal_type: animal type
|
|
1234
|
+
fraction_of_tan_in_liquid_manure_storage_system: (-) fraction of excreted N in animal urine (cf. Note 4)
|
|
1235
|
+
|
|
1236
|
+
Returns:
|
|
1237
|
+
|
|
1238
|
+
|
|
1239
|
+
Notes:
|
|
1240
|
+
1. Mineralization of organic N (fecal N and bedding N)
|
|
1241
|
+
2. Solid manure composted for ≥ 10 months; data from Chai et al. (2014); these values are used for compost passive and compost intensive beef and dairy cattle manure
|
|
1242
|
+
3. Solid manure stockpiled for ≥ 4 months; data from Chai et al. (2014); these values are also used for deep bedding beef and dairy cattle manure
|
|
1243
|
+
4. FracurinaryN is the fraction of TAN in the liquid manure storage system (includes liquid/slurry with natural crust, liquid/slurry with no natural crust, liquid/slurry with solid cover and deep pit under barn).
|
|
1244
|
+
5. Nitrification of TAN in liquid manure with natural crust (formed from manure, bedding, or waste forage) was considered since the natural crust can be assumed as similar to solid manure (stockpile) in terms of being aerobic. The N2O-N emission factor for liquid manure with a natural crust is 0.005 of total N IPCC (2006), which can be expressed as the TAN based EFs
|
|
1245
|
+
6. Nitrification of TAN in liquid manure with no natural crust is assumed to be zero because of anaerobic conditions
|
|
1246
|
+
7. All nitrified TAN (nitrate-N) was assumed to be denitrified (no leaching, runoff) in liquid systems.
|
|
1247
|
+
"""
|
|
1248
|
+
if animal_type.is_beef_cattle_type():
|
|
1249
|
+
# FracMineralized = Note 1.
|
|
1250
|
+
match state_type:
|
|
1251
|
+
# // Solid-compost - beef
|
|
1252
|
+
# // Note 2
|
|
1253
|
+
case ManureStateType.compost_intensive | ManureStateType.compost_passive:
|
|
1254
|
+
return FractionOfOrganicNitrogenMineralizedData(
|
|
1255
|
+
fraction_immobilized=0,
|
|
1256
|
+
fraction_mineralized=0.46,
|
|
1257
|
+
fraction_nitrified=0.25,
|
|
1258
|
+
fraction_denitrified=0,
|
|
1259
|
+
n2o_n=0.033,
|
|
1260
|
+
no_n=0.0033,
|
|
1261
|
+
n2_n=0.099,
|
|
1262
|
+
n_leached=0.0575)
|
|
1263
|
+
|
|
1264
|
+
# // Solid-stockpiled - beef
|
|
1265
|
+
# // Note 3
|
|
1266
|
+
case ManureStateType.deep_bedding | ManureStateType.solid_storage:
|
|
1267
|
+
return FractionOfOrganicNitrogenMineralizedData(
|
|
1268
|
+
fraction_immobilized=0,
|
|
1269
|
+
fraction_mineralized=0.28,
|
|
1270
|
+
fraction_nitrified=0.125,
|
|
1271
|
+
fraction_denitrified=0,
|
|
1272
|
+
n2o_n=0.033,
|
|
1273
|
+
no_n=0.0033,
|
|
1274
|
+
n2_n=0.099,
|
|
1275
|
+
n_leached=0.0575
|
|
1276
|
+
)
|
|
1277
|
+
elif animal_type.is_dairy_cattle_type():
|
|
1278
|
+
match state_type:
|
|
1279
|
+
# // Solid-compost - dairy
|
|
1280
|
+
# // Note 2
|
|
1281
|
+
case ManureStateType.compost_intensive | ManureStateType.compost_passive:
|
|
1282
|
+
return FractionOfOrganicNitrogenMineralizedData(
|
|
1283
|
+
fraction_immobilized=0,
|
|
1284
|
+
fraction_mineralized=0.46,
|
|
1285
|
+
fraction_nitrified=0.282,
|
|
1286
|
+
fraction_denitrified=0.152,
|
|
1287
|
+
n2o_n=0.037,
|
|
1288
|
+
no_n=0.0037,
|
|
1289
|
+
n2_n=0.111,
|
|
1290
|
+
n_leached=0.13)
|
|
1291
|
+
|
|
1292
|
+
# // Solid-stockpiled - dairy
|
|
1293
|
+
# // Note 3
|
|
1294
|
+
case ManureStateType.deep_bedding | ManureStateType.solid_storage:
|
|
1295
|
+
return FractionOfOrganicNitrogenMineralizedData(
|
|
1296
|
+
fraction_immobilized=0,
|
|
1297
|
+
fraction_mineralized=0.28,
|
|
1298
|
+
fraction_nitrified=0.141,
|
|
1299
|
+
fraction_denitrified=0.076,
|
|
1300
|
+
n2o_n=0.0185,
|
|
1301
|
+
no_n=0.0019,
|
|
1302
|
+
n2_n=0.0555,
|
|
1303
|
+
n_leached=0.065)
|
|
1304
|
+
|
|
1305
|
+
# // Liquid systems for both beef and dairy
|
|
1306
|
+
match state_type:
|
|
1307
|
+
# // Liquid with natural crust
|
|
1308
|
+
# // Note 5, 7
|
|
1309
|
+
case ManureStateType.liquid_with_natural_crust | ManureStateType.liquid_with_solid_cover | ManureStateType.deep_pit:
|
|
1310
|
+
return FractionOfOrganicNitrogenMineralizedData(
|
|
1311
|
+
fraction_immobilized=0,
|
|
1312
|
+
fraction_mineralized=0.1,
|
|
1313
|
+
fraction_nitrified=0.021 / min(1., fraction_of_tan_in_liquid_manure_storage_system),
|
|
1314
|
+
fraction_denitrified=0.021 / min(1., fraction_of_tan_in_liquid_manure_storage_system),
|
|
1315
|
+
n2o_n=0.005 / min(1., fraction_of_tan_in_liquid_manure_storage_system),
|
|
1316
|
+
no_n=0.0005 / min(1., fraction_of_tan_in_liquid_manure_storage_system),
|
|
1317
|
+
n2_n=0.015 / min(1., fraction_of_tan_in_liquid_manure_storage_system),
|
|
1318
|
+
n_leached=0)
|
|
1319
|
+
|
|
1320
|
+
# // Liquid without natural crust
|
|
1321
|
+
# // Note 6, 7
|
|
1322
|
+
case ManureStateType.liquid_no_crust:
|
|
1323
|
+
return FractionOfOrganicNitrogenMineralizedData(
|
|
1324
|
+
fraction_immobilized=0,
|
|
1325
|
+
fraction_mineralized=0.1,
|
|
1326
|
+
fraction_nitrified=0.0,
|
|
1327
|
+
fraction_denitrified=0,
|
|
1328
|
+
n2o_n=0,
|
|
1329
|
+
no_n=0,
|
|
1330
|
+
n2_n=0,
|
|
1331
|
+
n_leached=0
|
|
1332
|
+
)
|
|
1333
|
+
|
|
1334
|
+
return FractionOfOrganicNitrogenMineralizedData()
|
|
1335
|
+
|
|
1336
|
+
|
|
1337
|
+
def get_ammonia_emission_factor_for_storage_of_poultry_manure(
|
|
1338
|
+
animal_type: AnimalType
|
|
1339
|
+
) -> float:
|
|
1340
|
+
"""Returns the default ammonia emission factor for housing manure of Poultry-type animals.
|
|
1341
|
+
|
|
1342
|
+
Args:
|
|
1343
|
+
animal_type: animal type object
|
|
1344
|
+
|
|
1345
|
+
Returns:
|
|
1346
|
+
(kg NH3-N kg^-1 TAN): default ammonia emission factor for housing
|
|
1347
|
+
|
|
1348
|
+
References:
|
|
1349
|
+
Holos source code: https://github.com/holos-aafc/Holos/blob/396f1ab9bc7247e6d78766f9445c14d2eb7c0d9d/H.Core/Providers/Animals/DefaultAmmoniaEmissionFactorsForPoultryManureStorageProvider.cs#L7
|
|
1350
|
+
|
|
1351
|
+
"""
|
|
1352
|
+
if animal_type.is_chicken_type():
|
|
1353
|
+
if any((
|
|
1354
|
+
animal_type == AnimalType.chicken_hens,
|
|
1355
|
+
animal_type == AnimalType.layers)):
|
|
1356
|
+
res = 0.24
|
|
1357
|
+
else:
|
|
1358
|
+
res = 0.25
|
|
1359
|
+
else:
|
|
1360
|
+
# Turkeys
|
|
1361
|
+
res = 0.24
|
|
1362
|
+
|
|
1363
|
+
return res
|
|
1364
|
+
|
|
1365
|
+
|
|
1366
|
+
def get_ammonia_emission_factor_for_storage_of_beef_and_dairy_cattle_manure(
|
|
1367
|
+
storage_type: ManureStateType
|
|
1368
|
+
) -> float:
|
|
1369
|
+
"""Returns the default ammonia emission factor for housing of beef and dairy cattle manure.
|
|
1370
|
+
|
|
1371
|
+
Args:
|
|
1372
|
+
storage_type: manure handling system type
|
|
1373
|
+
|
|
1374
|
+
Returns:
|
|
1375
|
+
(kg NH3-N kg^-1 TAN): default ammonia emission factor for housing
|
|
1376
|
+
|
|
1377
|
+
References:
|
|
1378
|
+
Holos source code: https://github.com/holos-aafc/Holos/blob/396f1ab9bc7247e6d78766f9445c14d2eb7c0d9d/H.Core/Providers/Animals/Table_43_Beef_Dairy_Default_Emission_Factors_Provider.cs#L77
|
|
1379
|
+
|
|
1380
|
+
"""
|
|
1381
|
+
# Footnote 1: Read for data reference information.
|
|
1382
|
+
|
|
1383
|
+
if any((
|
|
1384
|
+
storage_type.is_liquid_manure(),
|
|
1385
|
+
storage_type == ManureStateType.deep_pit
|
|
1386
|
+
)):
|
|
1387
|
+
res = 0.13
|
|
1388
|
+
|
|
1389
|
+
elif storage_type.is_compost():
|
|
1390
|
+
res = 0.7
|
|
1391
|
+
|
|
1392
|
+
elif any((
|
|
1393
|
+
storage_type == ManureStateType.solid_storage,
|
|
1394
|
+
storage_type == ManureStateType.deep_bedding)):
|
|
1395
|
+
res = 0.35
|
|
1396
|
+
|
|
1397
|
+
else:
|
|
1398
|
+
res = 0
|
|
1399
|
+
|
|
1400
|
+
return res
|
|
1401
|
+
|
|
1402
|
+
|
|
1403
|
+
def get_emission_factor_for_volatilization_based_on_climate(
|
|
1404
|
+
mean_annual_precipitation: float,
|
|
1405
|
+
mean_annual_potential_evapotranspiration: float
|
|
1406
|
+
) -> float:
|
|
1407
|
+
"""Returns emission factor for volatilization (EF_volatilization)
|
|
1408
|
+
|
|
1409
|
+
Args:
|
|
1410
|
+
mean_annual_precipitation: (mm) mean annual precipitation
|
|
1411
|
+
mean_annual_potential_evapotranspiration: (mm) mean annual potential evapotranspiration
|
|
1412
|
+
|
|
1413
|
+
Returns:
|
|
1414
|
+
(kg(N2O-N) kg(N)-1): emission factor for volatilization
|
|
1415
|
+
|
|
1416
|
+
Notes:
|
|
1417
|
+
In IPCC (2019), Table 11.3: Disaggregation by climate for EFvolatilization (based on long-term averages):
|
|
1418
|
+
Wet climates occur in temperate and boreal zones where the ratio of annual precipitation (P) / potential evapotranspiration (PE) >1
|
|
1419
|
+
Dry climates occur in temperate and boreal zones where the ratio of annual P/PE <1
|
|
1420
|
+
|
|
1421
|
+
Holos Source Code:
|
|
1422
|
+
https://github.com/holos-aafc/Holos/blob/396f1ab9bc7247e6d78766f9445c14d2eb7c0d9d/H.Core/Providers/Animals/Table_36_Livestock_Emission_Conversion_Factors_Provider.cs#L515
|
|
1423
|
+
"""
|
|
1424
|
+
return 0.014 if mean_annual_precipitation > mean_annual_potential_evapotranspiration else 0.005
|
|
1425
|
+
|
|
1426
|
+
|
|
1427
|
+
class LivestockEmissionConversionFactorsData:
|
|
1428
|
+
def __init__(
|
|
1429
|
+
self,
|
|
1430
|
+
methane_conversion_factor: float = 0,
|
|
1431
|
+
n2o_direct_emission_factor: float = 0,
|
|
1432
|
+
volatilization_fraction: float = 0,
|
|
1433
|
+
emission_factor_volatilization: float = 0,
|
|
1434
|
+
leaching_fraction: float = 0,
|
|
1435
|
+
emission_factor_leach: float = 0,
|
|
1436
|
+
methane_enteric_rat: float = 0,
|
|
1437
|
+
methane_manure_rate: float = 0,
|
|
1438
|
+
nitrogen_excretion_rate: float = 0
|
|
1439
|
+
):
|
|
1440
|
+
"""class that hosts manure emission factors of livestock
|
|
1441
|
+
|
|
1442
|
+
Args:
|
|
1443
|
+
methane_conversion_factor: (kg kg^-1) Methane conversion factor of manure (MCF)
|
|
1444
|
+
n2o_direct_emission_factor: (kg(N2O-N) kg (N)-1) Direct N2O emission factor (EF_direct)
|
|
1445
|
+
volatilization_fraction: (kg(NH3-N) kg(N)-1) Fraction of volatilization (Frac_volatilization)
|
|
1446
|
+
emission_factor_volatilization: (kg(N2O-N) kg(N)-1) Emission factor for volatilization (EF_volatilization)
|
|
1447
|
+
leaching_fraction: (kg(N) kg(N)-1) Fraction of leaching (Frac_leach)
|
|
1448
|
+
emission_factor_leach: (kg(N2O-N) kg(N)-1) Emission factor for leaching (EF_leach)
|
|
1449
|
+
methane_enteric_rat: (kg Head-1 day-1)
|
|
1450
|
+
methane_manure_rate: (kg Head-1 day-1)
|
|
1451
|
+
nitrogen_excretion_rate: (kg Head-1 day-1)
|
|
1452
|
+
"""
|
|
1453
|
+
# public AnimalType AnimalType { get; set; }
|
|
1454
|
+
# public ManureStateType HandlingSystem { get; set; }
|
|
1455
|
+
|
|
1456
|
+
self.MethaneConversionFactor = methane_conversion_factor
|
|
1457
|
+
self.N2ODirectEmissionFactor = n2o_direct_emission_factor
|
|
1458
|
+
self.VolatilizationFraction = volatilization_fraction
|
|
1459
|
+
self.EmissionFactorVolatilization = emission_factor_volatilization
|
|
1460
|
+
self.LeachingFraction = leaching_fraction
|
|
1461
|
+
self.EmissionFactorLeach = emission_factor_leach
|
|
1462
|
+
self.MethaneEntericRat = methane_enteric_rat
|
|
1463
|
+
self.MethaneManureRate = methane_manure_rate
|
|
1464
|
+
self.NitrogenExcretionRate = nitrogen_excretion_rate
|
|
1465
|
+
|
|
1466
|
+
|
|
1467
|
+
def get_methane_conversion_factor(
|
|
1468
|
+
manure_state_type: ManureStateType,
|
|
1469
|
+
climate_zone: ClimateZones,
|
|
1470
|
+
) -> float:
|
|
1471
|
+
"""Returns the methane conversion factor by climate zone (kg kg-1)
|
|
1472
|
+
|
|
1473
|
+
Args:
|
|
1474
|
+
manure_state_type:
|
|
1475
|
+
climate_zone:
|
|
1476
|
+
|
|
1477
|
+
Returns:
|
|
1478
|
+
(kg kg-1) methane conversion factor
|
|
1479
|
+
|
|
1480
|
+
Holos Source Code:
|
|
1481
|
+
https://github.com/holos-aafc/Holos/blob/396f1ab9bc7247e6d78766f9445c14d2eb7c0d9d/H.Core/Providers/Animals/Table_37_MCF_By_Climate_Livestock_MansureSystem_Provider.cs#L16
|
|
1482
|
+
"""
|
|
1483
|
+
if any([
|
|
1484
|
+
manure_state_type == ManureStateType.solid_storage,
|
|
1485
|
+
manure_state_type == ManureStateType.solid
|
|
1486
|
+
]):
|
|
1487
|
+
match climate_zone:
|
|
1488
|
+
case ClimateZones.CoolTemperateMoist | ClimateZones.CoolTemperateDry | ClimateZones.BorealDry | ClimateZones.BorealMoist:
|
|
1489
|
+
return 0.02
|
|
1490
|
+
|
|
1491
|
+
case ClimateZones.WarmTemperateDry | ClimateZones.WarmTemperateMoist:
|
|
1492
|
+
return 0.04
|
|
1493
|
+
|
|
1494
|
+
if manure_state_type == ManureStateType.compost_intensive:
|
|
1495
|
+
match climate_zone:
|
|
1496
|
+
case ClimateZones.CoolTemperateMoist | ClimateZones.CoolTemperateDry | ClimateZones.BorealDry | ClimateZones.BorealMoist:
|
|
1497
|
+
return 0.005
|
|
1498
|
+
|
|
1499
|
+
case ClimateZones.WarmTemperateDry | ClimateZones.WarmTemperateMoist:
|
|
1500
|
+
return 0.01
|
|
1501
|
+
|
|
1502
|
+
if manure_state_type == ManureStateType.compost_passive:
|
|
1503
|
+
match climate_zone:
|
|
1504
|
+
case ClimateZones.CoolTemperateMoist | ClimateZones.CoolTemperateDry | ClimateZones.BorealDry | ClimateZones.BorealMoist:
|
|
1505
|
+
return 0.01
|
|
1506
|
+
|
|
1507
|
+
case ClimateZones.WarmTemperateDry | ClimateZones.WarmTemperateMoist:
|
|
1508
|
+
return 0.02
|
|
1509
|
+
|
|
1510
|
+
if manure_state_type == ManureStateType.deep_bedding:
|
|
1511
|
+
match climate_zone:
|
|
1512
|
+
case ClimateZones.CoolTemperateMoist:
|
|
1513
|
+
return 0.21
|
|
1514
|
+
case ClimateZones.CoolTemperateDry:
|
|
1515
|
+
return 0.26
|
|
1516
|
+
case ClimateZones.BorealDry | ClimateZones.BorealMoist:
|
|
1517
|
+
return 0.14
|
|
1518
|
+
case ClimateZones.WarmTemperateDry:
|
|
1519
|
+
return 0.37
|
|
1520
|
+
case ClimateZones.WarmTemperateMoist:
|
|
1521
|
+
return 0.41
|
|
1522
|
+
|
|
1523
|
+
if manure_state_type == ManureStateType.composted_in_vessel:
|
|
1524
|
+
match climate_zone:
|
|
1525
|
+
case ClimateZones.CoolTemperateMoist | ClimateZones.CoolTemperateDry | ClimateZones.BorealDry | ClimateZones.BorealMoist | ClimateZones.WarmTemperateDry | ClimateZones.WarmTemperateMoist:
|
|
1526
|
+
return 0.005
|
|
1527
|
+
|
|
1528
|
+
if manure_state_type == ManureStateType.daily_spread:
|
|
1529
|
+
match climate_zone:
|
|
1530
|
+
case ClimateZones.CoolTemperateMoist | ClimateZones.CoolTemperateDry | ClimateZones.BorealDry | ClimateZones.BorealMoist:
|
|
1531
|
+
return 0.001
|
|
1532
|
+
|
|
1533
|
+
case ClimateZones.WarmTemperateDry | ClimateZones.WarmTemperateMoist:
|
|
1534
|
+
return 0.005
|
|
1535
|
+
|
|
1536
|
+
if manure_state_type == ManureStateType.deep_pit:
|
|
1537
|
+
match climate_zone:
|
|
1538
|
+
case ClimateZones.CoolTemperateMoist:
|
|
1539
|
+
return 0.06
|
|
1540
|
+
case ClimateZones.CoolTemperateDry:
|
|
1541
|
+
return 0.08
|
|
1542
|
+
case ClimateZones.BorealDry:
|
|
1543
|
+
return 0.04
|
|
1544
|
+
case ClimateZones.BorealMoist:
|
|
1545
|
+
return 0.04
|
|
1546
|
+
case ClimateZones.WarmTemperateDry:
|
|
1547
|
+
return 0.15
|
|
1548
|
+
case ClimateZones.WarmTemperateMoist:
|
|
1549
|
+
return 0.13
|
|
1550
|
+
|
|
1551
|
+
# Pasture, etc. have non-temperature dependent values
|
|
1552
|
+
return 0
|
|
1553
|
+
|
|
1554
|
+
|
|
1555
|
+
def get_direct_emission_factor_based_on_climate(
|
|
1556
|
+
mean_annual_precipitation: float,
|
|
1557
|
+
mean_annual_potential_evapotranspiration: float
|
|
1558
|
+
) -> float:
|
|
1559
|
+
"""Returns the default N2O direct emission factor
|
|
1560
|
+
|
|
1561
|
+
Args:
|
|
1562
|
+
mean_annual_precipitation: (mm) mean annual precipitation
|
|
1563
|
+
mean_annual_potential_evapotranspiration: (mm) mean annual potential evapotranspiration
|
|
1564
|
+
|
|
1565
|
+
Returns:
|
|
1566
|
+
(kg(N2O-N) kg (N)-1) Direct N2O emission factor (EF_direct)
|
|
1567
|
+
|
|
1568
|
+
Holos Source Code:
|
|
1569
|
+
https://github.com/holos-aafc/Holos/blob/396f1ab9bc7247e6d78766f9445c14d2eb7c0d9d/H.Core/Providers/Animals/Table_36_Livestock_Emission_Conversion_Factors_Provider.cs#L534
|
|
1570
|
+
"""
|
|
1571
|
+
return 0.006 if mean_annual_precipitation > mean_annual_potential_evapotranspiration else 0.002
|
|
1572
|
+
|
|
1573
|
+
|
|
1574
|
+
def get_volatilization_fractions_from_land_applied_manure_data_for_swine_type(
|
|
1575
|
+
province: CanadianProvince,
|
|
1576
|
+
year: int
|
|
1577
|
+
) -> float:
|
|
1578
|
+
"""Returns the average volatilization fraction of applied swine manure
|
|
1579
|
+
|
|
1580
|
+
Args:
|
|
1581
|
+
province: Canadian Province class
|
|
1582
|
+
year: year
|
|
1583
|
+
|
|
1584
|
+
Returns:
|
|
1585
|
+
(kg NH3-N volatilized kg-1 manure N applied)
|
|
1586
|
+
|
|
1587
|
+
Holos Source Code:
|
|
1588
|
+
https://github.com/holos-aafc/Holos/blob/396f1ab9bc7247e6d78766f9445c14d2eb7c0d9d/H.Core/Providers/Animals/Table%2070/Table_62_Volatilization_Fractions_From_Land_Applied_Swine_Manure_Provider.cs#L23
|
|
1589
|
+
"""
|
|
1590
|
+
df = HolosTables.Table_62_Fractions_of_swine_N_volatilized
|
|
1591
|
+
return df.iloc[(df['Year'] - year).abs().idxmin()][province.value.abbreviation]
|
|
1592
|
+
|
|
1593
|
+
|
|
1594
|
+
def get_volatilization_fractions_from_land_applied_manure_data_for_dairy_cattle_type(
|
|
1595
|
+
province: CanadianProvince,
|
|
1596
|
+
year: int
|
|
1597
|
+
) -> float:
|
|
1598
|
+
"""Returns the average volatilization fraction of applied dairy cattle manure
|
|
1599
|
+
|
|
1600
|
+
Args:
|
|
1601
|
+
province: Canadian Province class
|
|
1602
|
+
year: year
|
|
1603
|
+
|
|
1604
|
+
Returns:
|
|
1605
|
+
(kg NH3-N volatilized kg-1 manure N applied)
|
|
1606
|
+
|
|
1607
|
+
Holos Source Code:
|
|
1608
|
+
https://github.com/holos-aafc/Holos/blob/396f1ab9bc7247e6d78766f9445c14d2eb7c0d9d/H.Core/Providers/Animals/Table%2069/Table_61_Volatilization_Fractions_From_Land_Applied_Dairy_Manure_Provider.cs#L48
|
|
1609
|
+
"""
|
|
1610
|
+
df = HolosTables.Table_61_Fractions_of_dairy_cattle_N_volatilized
|
|
1611
|
+
return df.iloc[(df['Year'] - year).abs().idxmin()][province.value.abbreviation]
|
|
1612
|
+
|
|
1613
|
+
|
|
1614
|
+
def get_volatilization_fraction_for_land_application(
|
|
1615
|
+
animal_type: AnimalType,
|
|
1616
|
+
province: CanadianProvince,
|
|
1617
|
+
year: int
|
|
1618
|
+
) -> float:
|
|
1619
|
+
"""Returns the average volatilization fraction of applied manure
|
|
1620
|
+
|
|
1621
|
+
Args:
|
|
1622
|
+
animal_type: animal type class
|
|
1623
|
+
province: Canadian Province class
|
|
1624
|
+
year: year
|
|
1625
|
+
|
|
1626
|
+
(kg NH3-N volatilized kg-1 manure N applied)
|
|
1627
|
+
|
|
1628
|
+
Holos Source Code:
|
|
1629
|
+
https://github.com/holos-aafc/Holos/blob/396f1ab9bc7247e6d78766f9445c14d2eb7c0d9d/H.Core/Providers/Animals/Table_36_Livestock_Emission_Conversion_Factors_Provider.cs#L96
|
|
1630
|
+
"""
|
|
1631
|
+
# Swine and dairy have more accurate volatilization fractions based on province and year
|
|
1632
|
+
if animal_type.is_swine_type():
|
|
1633
|
+
volatilization_fraction = get_volatilization_fractions_from_land_applied_manure_data_for_swine_type(
|
|
1634
|
+
province=province,
|
|
1635
|
+
year=year)
|
|
1636
|
+
|
|
1637
|
+
# return volatilizationFraction.ImpliedEmissionFactor;
|
|
1638
|
+
elif animal_type.is_dairy_cattle_type():
|
|
1639
|
+
volatilization_fraction = get_volatilization_fractions_from_land_applied_manure_data_for_dairy_cattle_type(
|
|
1640
|
+
province=province,
|
|
1641
|
+
year=year)
|
|
1642
|
+
|
|
1643
|
+
# return volatilizationFraction.ImpliedEmissionFactor;
|
|
1644
|
+
|
|
1645
|
+
else:
|
|
1646
|
+
volatilization_fraction = 0.21
|
|
1647
|
+
|
|
1648
|
+
return volatilization_fraction
|
|
1649
|
+
|
|
1650
|
+
|
|
1651
|
+
def get_land_application_factors(
|
|
1652
|
+
province: CanadianProvince,
|
|
1653
|
+
mean_annual_precipitation: float,
|
|
1654
|
+
mean_annual_evapotranspiration: float,
|
|
1655
|
+
growing_season_precipitation: float,
|
|
1656
|
+
growing_season_evapotranspiration: float,
|
|
1657
|
+
animal_type: AnimalType,
|
|
1658
|
+
year: int,
|
|
1659
|
+
soil_texture: SoilTexture
|
|
1660
|
+
) -> LivestockEmissionConversionFactorsData:
|
|
1661
|
+
"""Returns default manure application factor per region per year
|
|
1662
|
+
|
|
1663
|
+
Args:
|
|
1664
|
+
province: Canadian Province class
|
|
1665
|
+
mean_annual_precipitation: (mm) mean annual precipitation
|
|
1666
|
+
mean_annual_evapotranspiration: (mm) mean annual potential evapotranspiration
|
|
1667
|
+
growing_season_precipitation: (mm) total amount of precipitations during the growing season (e.g. may to oct.)
|
|
1668
|
+
growing_season_evapotranspiration: (mm) total amount of evapotranspiration during the growing season (e.g. may to oct.)
|
|
1669
|
+
animal_type: animal type class
|
|
1670
|
+
year: year
|
|
1671
|
+
soil_texture: soil texture as set in Holos
|
|
1672
|
+
|
|
1673
|
+
Holos Source Code:
|
|
1674
|
+
(1) https://github.com/RamiALBASHA/Holos/blob/71638efd97c84c6ded45e342ce664477df6f803f/H.Core/Providers/Animals/Table_36_Livestock_Emission_Conversion_Factors_Provider.cs#L41
|
|
1675
|
+
(2) https://github.com/holos-aafc/Holos/blob/267abf1066bb5494e5ec6a4085a85ab42dfa76c7/H.Core/Services/Initialization/Animals/AnimalInitializationService.Ammonia.cs#L55
|
|
1676
|
+
"""
|
|
1677
|
+
region = get_region(province=province)
|
|
1678
|
+
climate_dependent_emission_factor_for_volatilization = get_emission_factor_for_volatilization_based_on_climate(
|
|
1679
|
+
mean_annual_precipitation=mean_annual_precipitation,
|
|
1680
|
+
mean_annual_potential_evapotranspiration=mean_annual_evapotranspiration)
|
|
1681
|
+
|
|
1682
|
+
climate_dependent_direct_emission_factor = get_direct_emission_factor_based_on_climate(
|
|
1683
|
+
mean_annual_precipitation=mean_annual_precipitation,
|
|
1684
|
+
mean_annual_potential_evapotranspiration=mean_annual_evapotranspiration)
|
|
1685
|
+
|
|
1686
|
+
factors = LivestockEmissionConversionFactorsData(
|
|
1687
|
+
methane_conversion_factor=0.0047,
|
|
1688
|
+
n2o_direct_emission_factor=climate_dependent_direct_emission_factor,
|
|
1689
|
+
volatilization_fraction=0.21,
|
|
1690
|
+
emission_factor_volatilization=climate_dependent_emission_factor_for_volatilization)
|
|
1691
|
+
|
|
1692
|
+
factors.EmissionFactorLeach = Defaults.EmissionFactorForLeachingAndRunoff
|
|
1693
|
+
|
|
1694
|
+
if region == Region.WesternCanada:
|
|
1695
|
+
factors.N2ODirectEmissionFactor = 0.00043
|
|
1696
|
+
else:
|
|
1697
|
+
if soil_texture == SoilTexture.Fine:
|
|
1698
|
+
factors.N2ODirectEmissionFactor = 0.0078
|
|
1699
|
+
elif soil_texture == SoilTexture.Medium:
|
|
1700
|
+
factors.N2ODirectEmissionFactor = 0.0062
|
|
1701
|
+
else:
|
|
1702
|
+
# SoilTexture = Coarse
|
|
1703
|
+
# Footnote 1
|
|
1704
|
+
factors.N2ODirectEmissionFactor = 0.0047
|
|
1705
|
+
|
|
1706
|
+
factors.VolatilizationFraction = get_volatilization_fraction_for_land_application(
|
|
1707
|
+
animal_type=animal_type,
|
|
1708
|
+
province=province,
|
|
1709
|
+
year=year)
|
|
1710
|
+
|
|
1711
|
+
# This part of the code comes from Holos Source Code (2)
|
|
1712
|
+
factors.LeachingFraction = calculate_fraction_of_nitrogen_lost_by_leaching_and_runoff(
|
|
1713
|
+
growing_season_precipitation=growing_season_precipitation,
|
|
1714
|
+
growing_season_evapotranspiration=growing_season_evapotranspiration)
|
|
1715
|
+
|
|
1716
|
+
return factors
|
|
1717
|
+
|
|
1718
|
+
|
|
1719
|
+
def get_manure_emission_factors(
|
|
1720
|
+
manure_state_type: ManureStateType,
|
|
1721
|
+
mean_annual_precipitation: float,
|
|
1722
|
+
mean_annual_temperature: float,
|
|
1723
|
+
mean_annual_evapotranspiration: float,
|
|
1724
|
+
growing_season_precipitation: float,
|
|
1725
|
+
growing_season_evapotranspiration: float,
|
|
1726
|
+
animal_type: AnimalType,
|
|
1727
|
+
province: CanadianProvince,
|
|
1728
|
+
year: int,
|
|
1729
|
+
soil_texture: SoilTexture
|
|
1730
|
+
) -> LivestockEmissionConversionFactorsData:
|
|
1731
|
+
"""Sets the emission factors for manure
|
|
1732
|
+
|
|
1733
|
+
Args:
|
|
1734
|
+
manure_state_type: ManureStateType class instance
|
|
1735
|
+
mean_annual_precipitation: (mm) mean annual precipitation
|
|
1736
|
+
mean_annual_temperature: (degrees Celsius) mean annual air temperature
|
|
1737
|
+
mean_annual_evapotranspiration: (mm) mean annual potential evapotranspiration
|
|
1738
|
+
growing_season_precipitation: (mm) total amount of precipitations during the growing season (e.g. may to oct.)
|
|
1739
|
+
growing_season_evapotranspiration: (mm) total amount of evapotranspiration during the growing season (e.g. may to oct.)
|
|
1740
|
+
animal_type: animal type class
|
|
1741
|
+
province: CanadianProvince class instance
|
|
1742
|
+
year: year
|
|
1743
|
+
soil_texture: soil texture as set in Holos
|
|
1744
|
+
|
|
1745
|
+
Returns:
|
|
1746
|
+
|
|
1747
|
+
Holos Source Code:
|
|
1748
|
+
https://github.com/RamiALBASHA/Holos/blob/71638efd97c84c6ded45e342ce664477df6f803f/H.Core/Providers/Animals/Table_36_Livestock_Emission_Conversion_Factors_Provider.cs#L117
|
|
1749
|
+
"""
|
|
1750
|
+
climate_dependent_methane_conversion_factor = get_methane_conversion_factor(
|
|
1751
|
+
manure_state_type=manure_state_type,
|
|
1752
|
+
climate_zone=get_climate_zone(
|
|
1753
|
+
mean_annual_temperature=mean_annual_temperature,
|
|
1754
|
+
mean_annual_precipitation=mean_annual_precipitation,
|
|
1755
|
+
mean_annual_potential_evapotranspiration=mean_annual_evapotranspiration))
|
|
1756
|
+
|
|
1757
|
+
climate_dependent_emission_factor_for_volatilization = get_emission_factor_for_volatilization_based_on_climate(
|
|
1758
|
+
mean_annual_precipitation=mean_annual_precipitation,
|
|
1759
|
+
mean_annual_potential_evapotranspiration=mean_annual_evapotranspiration)
|
|
1760
|
+
|
|
1761
|
+
# All factors are the same when considering any manure on pasture
|
|
1762
|
+
if any([
|
|
1763
|
+
manure_state_type == ManureStateType.pasture,
|
|
1764
|
+
manure_state_type == ManureStateType.paddock,
|
|
1765
|
+
manure_state_type == ManureStateType.range
|
|
1766
|
+
]):
|
|
1767
|
+
return get_land_application_factors(
|
|
1768
|
+
province=province,
|
|
1769
|
+
mean_annual_precipitation=mean_annual_precipitation,
|
|
1770
|
+
mean_annual_evapotranspiration=mean_annual_evapotranspiration,
|
|
1771
|
+
growing_season_precipitation=growing_season_precipitation,
|
|
1772
|
+
growing_season_evapotranspiration=growing_season_evapotranspiration,
|
|
1773
|
+
animal_type=animal_type,
|
|
1774
|
+
year=year,
|
|
1775
|
+
soil_texture=soil_texture)
|
|
1776
|
+
|
|
1777
|
+
# The following factors are for animals not on pasture.
|
|
1778
|
+
category = animal_type.get_component_category_from_animal_type()
|
|
1779
|
+
|
|
1780
|
+
match category:
|
|
1781
|
+
case ComponentCategory.BeefProduction:
|
|
1782
|
+
match manure_state_type:
|
|
1783
|
+
case ManureStateType.solid_storage:
|
|
1784
|
+
return LivestockEmissionConversionFactorsData(
|
|
1785
|
+
methane_conversion_factor=climate_dependent_methane_conversion_factor,
|
|
1786
|
+
n2o_direct_emission_factor=0.01,
|
|
1787
|
+
volatilization_fraction=0.45,
|
|
1788
|
+
emission_factor_volatilization=climate_dependent_emission_factor_for_volatilization,
|
|
1789
|
+
leaching_fraction=0.02,
|
|
1790
|
+
emission_factor_leach=0.011)
|
|
1791
|
+
|
|
1792
|
+
case ManureStateType.compost_intensive:
|
|
1793
|
+
return LivestockEmissionConversionFactorsData(
|
|
1794
|
+
methane_conversion_factor=climate_dependent_methane_conversion_factor,
|
|
1795
|
+
n2o_direct_emission_factor=0.005,
|
|
1796
|
+
volatilization_fraction=0.65,
|
|
1797
|
+
emission_factor_volatilization=climate_dependent_emission_factor_for_volatilization,
|
|
1798
|
+
leaching_fraction=0.06,
|
|
1799
|
+
emission_factor_leach=0.011)
|
|
1800
|
+
|
|
1801
|
+
case ManureStateType.compost_passive:
|
|
1802
|
+
return LivestockEmissionConversionFactorsData(
|
|
1803
|
+
methane_conversion_factor=climate_dependent_methane_conversion_factor,
|
|
1804
|
+
n2o_direct_emission_factor=0.005,
|
|
1805
|
+
volatilization_fraction=0.60,
|
|
1806
|
+
emission_factor_volatilization=climate_dependent_emission_factor_for_volatilization,
|
|
1807
|
+
leaching_fraction=0.04,
|
|
1808
|
+
emission_factor_leach=0.011)
|
|
1809
|
+
|
|
1810
|
+
case ManureStateType.deep_bedding:
|
|
1811
|
+
return LivestockEmissionConversionFactorsData(
|
|
1812
|
+
methane_conversion_factor=climate_dependent_methane_conversion_factor,
|
|
1813
|
+
n2o_direct_emission_factor=0.01,
|
|
1814
|
+
volatilization_fraction=0.25,
|
|
1815
|
+
emission_factor_volatilization=climate_dependent_emission_factor_for_volatilization,
|
|
1816
|
+
leaching_fraction=0.035,
|
|
1817
|
+
emission_factor_leach=0.011)
|
|
1818
|
+
|
|
1819
|
+
case ManureStateType.anaerobic_digester:
|
|
1820
|
+
return LivestockEmissionConversionFactorsData(
|
|
1821
|
+
methane_conversion_factor=0.01, # Footnote 4
|
|
1822
|
+
n2o_direct_emission_factor=0.0006,
|
|
1823
|
+
volatilization_fraction=0.1,
|
|
1824
|
+
emission_factor_volatilization=climate_dependent_emission_factor_for_volatilization,
|
|
1825
|
+
leaching_fraction=0.0,
|
|
1826
|
+
emission_factor_leach=0.011)
|
|
1827
|
+
|
|
1828
|
+
case _:
|
|
1829
|
+
# raise ValueError(
|
|
1830
|
+
# f"Unable to get data for manure state type: {manure_state_type}. Returning default value.")
|
|
1831
|
+
return LivestockEmissionConversionFactorsData()
|
|
1832
|
+
|
|
1833
|
+
case ComponentCategory.Dairy:
|
|
1834
|
+
match manure_state_type:
|
|
1835
|
+
case ManureStateType.daily_spread:
|
|
1836
|
+
return LivestockEmissionConversionFactorsData(
|
|
1837
|
+
methane_conversion_factor=climate_dependent_methane_conversion_factor,
|
|
1838
|
+
n2o_direct_emission_factor=0.0,
|
|
1839
|
+
volatilization_fraction=0.07,
|
|
1840
|
+
emission_factor_volatilization=climate_dependent_emission_factor_for_volatilization,
|
|
1841
|
+
leaching_fraction=0,
|
|
1842
|
+
emission_factor_leach=0.011)
|
|
1843
|
+
|
|
1844
|
+
case ManureStateType.solid_storage:
|
|
1845
|
+
return LivestockEmissionConversionFactorsData(
|
|
1846
|
+
methane_conversion_factor=climate_dependent_methane_conversion_factor,
|
|
1847
|
+
n2o_direct_emission_factor=0.01,
|
|
1848
|
+
volatilization_fraction=0.3,
|
|
1849
|
+
emission_factor_volatilization=climate_dependent_emission_factor_for_volatilization,
|
|
1850
|
+
leaching_fraction=0.02,
|
|
1851
|
+
emission_factor_leach=0.011)
|
|
1852
|
+
|
|
1853
|
+
case ManureStateType.compost_intensive:
|
|
1854
|
+
return LivestockEmissionConversionFactorsData(
|
|
1855
|
+
methane_conversion_factor=climate_dependent_methane_conversion_factor,
|
|
1856
|
+
n2o_direct_emission_factor=0.005,
|
|
1857
|
+
volatilization_fraction=0.5,
|
|
1858
|
+
emission_factor_volatilization=climate_dependent_emission_factor_for_volatilization,
|
|
1859
|
+
leaching_fraction=0.06,
|
|
1860
|
+
emission_factor_leach=0.011)
|
|
1861
|
+
|
|
1862
|
+
case ManureStateType.compost_passive:
|
|
1863
|
+
return LivestockEmissionConversionFactorsData(
|
|
1864
|
+
methane_conversion_factor=climate_dependent_methane_conversion_factor,
|
|
1865
|
+
n2o_direct_emission_factor=0.005,
|
|
1866
|
+
volatilization_fraction=0.45,
|
|
1867
|
+
emission_factor_volatilization=climate_dependent_emission_factor_for_volatilization,
|
|
1868
|
+
leaching_fraction=0.04,
|
|
1869
|
+
emission_factor_leach=0.011)
|
|
1870
|
+
|
|
1871
|
+
case ManureStateType.deep_bedding:
|
|
1872
|
+
return LivestockEmissionConversionFactorsData(
|
|
1873
|
+
methane_conversion_factor=climate_dependent_methane_conversion_factor,
|
|
1874
|
+
n2o_direct_emission_factor=0.01,
|
|
1875
|
+
volatilization_fraction=0.25,
|
|
1876
|
+
emission_factor_volatilization=climate_dependent_emission_factor_for_volatilization,
|
|
1877
|
+
leaching_fraction=0.035,
|
|
1878
|
+
emission_factor_leach=0.011)
|
|
1879
|
+
|
|
1880
|
+
case ManureStateType.liquid_with_natural_crust:
|
|
1881
|
+
return LivestockEmissionConversionFactorsData(
|
|
1882
|
+
n2o_direct_emission_factor=0.005,
|
|
1883
|
+
volatilization_fraction=0.3,
|
|
1884
|
+
emission_factor_volatilization=climate_dependent_emission_factor_for_volatilization,
|
|
1885
|
+
leaching_fraction=0,
|
|
1886
|
+
emission_factor_leach=0.011)
|
|
1887
|
+
|
|
1888
|
+
case ManureStateType.liquid_no_crust:
|
|
1889
|
+
return LivestockEmissionConversionFactorsData(
|
|
1890
|
+
n2o_direct_emission_factor=0.0,
|
|
1891
|
+
volatilization_fraction=0.48,
|
|
1892
|
+
emission_factor_volatilization=climate_dependent_emission_factor_for_volatilization,
|
|
1893
|
+
leaching_fraction=0,
|
|
1894
|
+
emission_factor_leach=0.011)
|
|
1895
|
+
|
|
1896
|
+
case ManureStateType.liquid_with_solid_cover:
|
|
1897
|
+
return LivestockEmissionConversionFactorsData(
|
|
1898
|
+
n2o_direct_emission_factor=0.005,
|
|
1899
|
+
volatilization_fraction=0.1,
|
|
1900
|
+
emission_factor_volatilization=climate_dependent_emission_factor_for_volatilization,
|
|
1901
|
+
leaching_fraction=0,
|
|
1902
|
+
emission_factor_leach=0.011)
|
|
1903
|
+
|
|
1904
|
+
case ManureStateType.deep_pit:
|
|
1905
|
+
return LivestockEmissionConversionFactorsData(
|
|
1906
|
+
methane_conversion_factor=climate_dependent_methane_conversion_factor,
|
|
1907
|
+
n2o_direct_emission_factor=0.002,
|
|
1908
|
+
volatilization_fraction=0.28,
|
|
1909
|
+
emission_factor_volatilization=climate_dependent_emission_factor_for_volatilization,
|
|
1910
|
+
leaching_fraction=0,
|
|
1911
|
+
emission_factor_leach=0.011)
|
|
1912
|
+
|
|
1913
|
+
case ManureStateType.anaerobic_digester:
|
|
1914
|
+
return LivestockEmissionConversionFactorsData(
|
|
1915
|
+
methane_conversion_factor=0.01, # Footnote 4
|
|
1916
|
+
n2o_direct_emission_factor=0.0006,
|
|
1917
|
+
volatilization_fraction=0.1,
|
|
1918
|
+
emission_factor_volatilization=climate_dependent_emission_factor_for_volatilization,
|
|
1919
|
+
emission_factor_leach=0.011)
|
|
1920
|
+
|
|
1921
|
+
case _:
|
|
1922
|
+
raise ValueError(
|
|
1923
|
+
f": Unable to get data for manure state type: {manure_state_type}. Returning default value.")
|
|
1924
|
+
|
|
1925
|
+
# return Table_36_Livestock_Emission_Conversion_Factors_Data()
|
|
1926
|
+
|
|
1927
|
+
case ComponentCategory.Swine:
|
|
1928
|
+
match manure_state_type:
|
|
1929
|
+
case ManureStateType.composted_in_vessel:
|
|
1930
|
+
return LivestockEmissionConversionFactorsData(
|
|
1931
|
+
methane_conversion_factor=0.005,
|
|
1932
|
+
n2o_direct_emission_factor=0.006,
|
|
1933
|
+
volatilization_fraction=0.6,
|
|
1934
|
+
emission_factor_volatilization=climate_dependent_emission_factor_for_volatilization,
|
|
1935
|
+
leaching_fraction=0,
|
|
1936
|
+
emission_factor_leach=0.011)
|
|
1937
|
+
|
|
1938
|
+
case ManureStateType.liquid_with_natural_crust:
|
|
1939
|
+
return LivestockEmissionConversionFactorsData(
|
|
1940
|
+
methane_conversion_factor=0.0,
|
|
1941
|
+
n2o_direct_emission_factor=0.005,
|
|
1942
|
+
volatilization_fraction=0.3,
|
|
1943
|
+
emission_factor_volatilization=climate_dependent_emission_factor_for_volatilization,
|
|
1944
|
+
leaching_fraction=0,
|
|
1945
|
+
emission_factor_leach=0.011)
|
|
1946
|
+
|
|
1947
|
+
case ManureStateType.liquid_no_crust:
|
|
1948
|
+
return LivestockEmissionConversionFactorsData(
|
|
1949
|
+
methane_conversion_factor=0.0,
|
|
1950
|
+
n2o_direct_emission_factor=0.0,
|
|
1951
|
+
volatilization_fraction=0.48,
|
|
1952
|
+
emission_factor_volatilization=climate_dependent_emission_factor_for_volatilization,
|
|
1953
|
+
leaching_fraction=0,
|
|
1954
|
+
emission_factor_leach=0.011)
|
|
1955
|
+
|
|
1956
|
+
case ManureStateType.liquid_with_solid_cover:
|
|
1957
|
+
return LivestockEmissionConversionFactorsData(
|
|
1958
|
+
methane_conversion_factor=0.0,
|
|
1959
|
+
n2o_direct_emission_factor=0.005,
|
|
1960
|
+
volatilization_fraction=0.1,
|
|
1961
|
+
emission_factor_volatilization=climate_dependent_emission_factor_for_volatilization,
|
|
1962
|
+
leaching_fraction=0,
|
|
1963
|
+
emission_factor_leach=0.011)
|
|
1964
|
+
|
|
1965
|
+
case ManureStateType.deep_pit:
|
|
1966
|
+
return LivestockEmissionConversionFactorsData(
|
|
1967
|
+
methane_conversion_factor=climate_dependent_methane_conversion_factor,
|
|
1968
|
+
n2o_direct_emission_factor=0.002,
|
|
1969
|
+
volatilization_fraction=0.25,
|
|
1970
|
+
emission_factor_volatilization=climate_dependent_emission_factor_for_volatilization,
|
|
1971
|
+
emission_factor_leach=0.011)
|
|
1972
|
+
|
|
1973
|
+
case ManureStateType.anaerobic_digester:
|
|
1974
|
+
return LivestockEmissionConversionFactorsData(
|
|
1975
|
+
methane_conversion_factor=0.01, # Footnote 4
|
|
1976
|
+
n2o_direct_emission_factor=0.0006,
|
|
1977
|
+
volatilization_fraction=0.1, # Footnote 5
|
|
1978
|
+
emission_factor_volatilization=climate_dependent_emission_factor_for_volatilization,
|
|
1979
|
+
emission_factor_leach=0.011)
|
|
1980
|
+
|
|
1981
|
+
case _:
|
|
1982
|
+
raise ValueError(
|
|
1983
|
+
f"Unable to get data for manure state type: {manure_state_type}. Returning default value.")
|
|
1984
|
+
# return Table_36_Livestock_Emission_Conversion_Factors_Data()
|
|
1985
|
+
|
|
1986
|
+
case ComponentCategory.Sheep:
|
|
1987
|
+
match manure_state_type:
|
|
1988
|
+
case ManureStateType.solid_storage:
|
|
1989
|
+
return LivestockEmissionConversionFactorsData(
|
|
1990
|
+
methane_conversion_factor=climate_dependent_methane_conversion_factor,
|
|
1991
|
+
n2o_direct_emission_factor=0.01,
|
|
1992
|
+
volatilization_fraction=0.12,
|
|
1993
|
+
emission_factor_volatilization=climate_dependent_emission_factor_for_volatilization,
|
|
1994
|
+
leaching_fraction=0.02,
|
|
1995
|
+
emission_factor_leach=0.011)
|
|
1996
|
+
|
|
1997
|
+
case _:
|
|
1998
|
+
raise ValueError(
|
|
1999
|
+
f"Unable to get data for manure state type: {manure_state_type}. Returning default value.")
|
|
2000
|
+
# return Table_36_Livestock_Emission_Conversion_Factors_Data();
|
|
2001
|
+
|
|
2002
|
+
case ComponentCategory.Poultry:
|
|
2003
|
+
if manure_state_type == ManureStateType.anaerobic_digester:
|
|
2004
|
+
return LivestockEmissionConversionFactorsData(
|
|
2005
|
+
methane_conversion_factor=0.01, # Footnote 7
|
|
2006
|
+
n2o_direct_emission_factor=0.0006,
|
|
2007
|
+
volatilization_fraction=0.1,
|
|
2008
|
+
emission_factor_volatilization=climate_dependent_emission_factor_for_volatilization,
|
|
2009
|
+
leaching_fraction=0,
|
|
2010
|
+
emission_factor_leach=0.011)
|
|
2011
|
+
|
|
2012
|
+
if manure_state_type == ManureStateType.solid_storage_with_or_without_litter:
|
|
2013
|
+
# Bedding with litter
|
|
2014
|
+
return LivestockEmissionConversionFactorsData(
|
|
2015
|
+
methane_conversion_factor=0.015, # Footnote 7
|
|
2016
|
+
n2o_direct_emission_factor=0.001, # Footnote 7
|
|
2017
|
+
volatilization_fraction=0.4,
|
|
2018
|
+
emission_factor_volatilization=climate_dependent_emission_factor_for_volatilization,
|
|
2019
|
+
leaching_fraction=0,
|
|
2020
|
+
emission_factor_leach=0.011)
|
|
2021
|
+
|
|
2022
|
+
raise ValueError(
|
|
2023
|
+
f"Unable to get data for manure state type: {manure_state_type}. Returning default value.")
|
|
2024
|
+
|
|
2025
|
+
# return Table_36_Livestock_Emission_Conversion_Factors_Data()
|
|
2026
|
+
|
|
2027
|
+
case ComponentCategory.OtherLivestock:
|
|
2028
|
+
match manure_state_type:
|
|
2029
|
+
case ManureStateType.solid_storage:
|
|
2030
|
+
return LivestockEmissionConversionFactorsData(
|
|
2031
|
+
methane_conversion_factor=climate_dependent_methane_conversion_factor,
|
|
2032
|
+
n2o_direct_emission_factor=0.01,
|
|
2033
|
+
volatilization_fraction=0.12,
|
|
2034
|
+
emission_factor_volatilization=climate_dependent_emission_factor_for_volatilization,
|
|
2035
|
+
leaching_fraction=0.02,
|
|
2036
|
+
emission_factor_leach=0.011)
|
|
2037
|
+
|
|
2038
|
+
case _:
|
|
2039
|
+
raise ValueError(
|
|
2040
|
+
f"Unable to get data for manure state type: {manure_state_type}. Returning default value.")
|
|
2041
|
+
# return Table_36_Livestock_Emission_Conversion_Factors_Data();
|
|
2042
|
+
|
|
2043
|
+
# Unknown component category (or no values for category yet)
|
|
2044
|
+
case _:
|
|
2045
|
+
raise ValueError(
|
|
2046
|
+
' '.join([
|
|
2047
|
+
f"Unable to get data for manure state type '{manure_state_type}'",
|
|
2048
|
+
f"and component category '{category}'.",
|
|
2049
|
+
"Returning default value."
|
|
2050
|
+
]))
|
|
2051
|
+
# return Table_36_Livestock_Emission_Conversion_Factors_Data();
|
|
2052
|
+
|
|
2053
|
+
|
|
2054
|
+
def get_manure_excretion_rate(
|
|
2055
|
+
animal_type: AnimalType
|
|
2056
|
+
) -> float:
|
|
2057
|
+
"""Returns the manure excretion rate of animals
|
|
2058
|
+
|
|
2059
|
+
Args:
|
|
2060
|
+
animal_type: AnimalType class instance
|
|
2061
|
+
|
|
2062
|
+
Returns:
|
|
2063
|
+
(kg head-1 day-1) animal excretion rate
|
|
2064
|
+
|
|
2065
|
+
Holos Source Code:
|
|
2066
|
+
https://github.com/holos-aafc/Holos/blob/97331845af308fe8aab6267edad4bbda6f5938b6/H.Core/Providers/Animals/Table_29_Default_Manure_Excreted_Provider.cs#L100
|
|
2067
|
+
|
|
2068
|
+
"""
|
|
2069
|
+
_excretionRates = HolosTables.Table_29_Percentage_Total_Manure_Produced_In_Systems
|
|
2070
|
+
|
|
2071
|
+
animal_type_lookup = animal_type
|
|
2072
|
+
if animal_type.is_beef_cattle_type():
|
|
2073
|
+
animal_type_lookup = AnimalType.beef
|
|
2074
|
+
elif animal_type.is_dairy_cattle_type():
|
|
2075
|
+
animal_type_lookup = AnimalType.dairy
|
|
2076
|
+
elif animal_type.is_sheep_type():
|
|
2077
|
+
animal_type_lookup = AnimalType.sheep
|
|
2078
|
+
elif animal_type.is_swine_type():
|
|
2079
|
+
animal_type_lookup = AnimalType.swine
|
|
2080
|
+
elif animal_type.is_turkey_type():
|
|
2081
|
+
animal_type_lookup = AnimalType.turkeys
|
|
2082
|
+
elif animal_type.is_poultry_type():
|
|
2083
|
+
if animal_type == AnimalType.chicken_hens:
|
|
2084
|
+
animal_type_lookup = AnimalType.layers
|
|
2085
|
+
|
|
2086
|
+
return _excretionRates.loc[animal_type_lookup, 'manure_excreted_rate']
|
|
2087
|
+
|
|
2088
|
+
|
|
2089
|
+
def convert_manure_state_type_name(name: str) -> ManureStateType:
|
|
2090
|
+
cleaned_input = name.lower().strip().replace(' ', '').replace('-', '').replace('/', '')
|
|
2091
|
+
match cleaned_input:
|
|
2092
|
+
case "pasture" | "pasturerangepaddock":
|
|
2093
|
+
return ManureStateType.pasture
|
|
2094
|
+
|
|
2095
|
+
case "deepbedding":
|
|
2096
|
+
return ManureStateType.deep_bedding
|
|
2097
|
+
|
|
2098
|
+
case "solidstorage" | "solidstoragestockpiled":
|
|
2099
|
+
return ManureStateType.solid_storage
|
|
2100
|
+
|
|
2101
|
+
case "solidstoragewithorwithoutlitter":
|
|
2102
|
+
return ManureStateType.solid_storage_with_or_without_litter
|
|
2103
|
+
|
|
2104
|
+
case "compostedpassive" | "compostpassive" | "compostpassivewindrow":
|
|
2105
|
+
return ManureStateType.compost_passive
|
|
2106
|
+
|
|
2107
|
+
case "compostedintensive" | "compostintensive" | "compostintensivewindrow":
|
|
2108
|
+
return ManureStateType.compost_intensive
|
|
2109
|
+
|
|
2110
|
+
case "compostedinvessel":
|
|
2111
|
+
return ManureStateType.composted_in_vessel
|
|
2112
|
+
|
|
2113
|
+
case "composted":
|
|
2114
|
+
return ManureStateType.composted
|
|
2115
|
+
|
|
2116
|
+
case "anaerobicdigestion" | "anaerobicdigestor":
|
|
2117
|
+
return ManureStateType.anaerobic_digester
|
|
2118
|
+
|
|
2119
|
+
case "deeppit" | "deeppitunderbarn":
|
|
2120
|
+
return ManureStateType.deep_pit
|
|
2121
|
+
|
|
2122
|
+
case "liquidsolidcover" | "liquidwithsolidcover" | "liquidslurrywithsolidcover":
|
|
2123
|
+
return ManureStateType.liquid_with_solid_cover
|
|
2124
|
+
|
|
2125
|
+
case "liquidnaturalcrust" | "liquidwithnaturalcrust" | "liquidslurrywithnaturalcrust":
|
|
2126
|
+
return ManureStateType.liquid_with_natural_crust
|
|
2127
|
+
|
|
2128
|
+
case "liquidnocrust" | "liquidwithnocrust" | "liquidslurrywithnonaturalcrust":
|
|
2129
|
+
return ManureStateType.liquid_no_crust
|
|
2130
|
+
|
|
2131
|
+
case "dailyspread":
|
|
2132
|
+
return ManureStateType.daily_spread
|
|
2133
|
+
|
|
2134
|
+
case _:
|
|
2135
|
+
# raise ValueError(f"was not able to convert {name}. Returning {ManureStateType.not_selected}")
|
|
2136
|
+
return ManureStateType.not_selected
|
|
2137
|
+
|
|
2138
|
+
|
|
2139
|
+
class ManureComposition:
|
|
2140
|
+
def __init__(
|
|
2141
|
+
self,
|
|
2142
|
+
moisture_content: float,
|
|
2143
|
+
nitrogen_content: float,
|
|
2144
|
+
carbon_content: float,
|
|
2145
|
+
phosphorus_content: float,
|
|
2146
|
+
carbon_to_nitrogen_ratio: float,
|
|
2147
|
+
volatile_solid_content: float
|
|
2148
|
+
):
|
|
2149
|
+
self.moisture_content = moisture_content
|
|
2150
|
+
self.nitrogen_content = nitrogen_content
|
|
2151
|
+
self.carbon_content = carbon_content
|
|
2152
|
+
self.phosphorus_content = phosphorus_content
|
|
2153
|
+
self.carbon_to_nitrogen_ratio = carbon_to_nitrogen_ratio
|
|
2154
|
+
self.volatile_solid_content = volatile_solid_content
|
|
2155
|
+
|
|
2156
|
+
|
|
2157
|
+
def get_default_manure_composition_data(
|
|
2158
|
+
animal_type: AnimalType,
|
|
2159
|
+
manure_state_type: ManureStateType
|
|
2160
|
+
) -> ManureComposition:
|
|
2161
|
+
"""Returns the default manure composition values depending on animal type and manure state (handling system) type
|
|
2162
|
+
|
|
2163
|
+
Args:
|
|
2164
|
+
animal_type: AnimalType class instance
|
|
2165
|
+
manure_state_type: ManureStateType class instance
|
|
2166
|
+
|
|
2167
|
+
Returns:
|
|
2168
|
+
ManureComposition class instance
|
|
2169
|
+
|
|
2170
|
+
Holos Source Code:
|
|
2171
|
+
https://github.com/holos-aafc/Holos/blob/97331845af308fe8aab6267edad4bbda6f5938b6/H.Core/Models/Farm.Manure.cs#L34
|
|
2172
|
+
"""
|
|
2173
|
+
|
|
2174
|
+
# var defaultValue = new DefaultManureCompositionData();
|
|
2175
|
+
|
|
2176
|
+
if animal_type.is_beef_cattle_type():
|
|
2177
|
+
animal_lookup_type = AnimalType.beef
|
|
2178
|
+
elif animal_type.is_dairy_cattle_type():
|
|
2179
|
+
animal_lookup_type = AnimalType.dairy
|
|
2180
|
+
elif animal_type.is_sheep_type():
|
|
2181
|
+
animal_lookup_type = AnimalType.sheep
|
|
2182
|
+
elif animal_type.is_swine_type():
|
|
2183
|
+
animal_lookup_type = AnimalType.swine
|
|
2184
|
+
elif animal_type.is_poultry_type():
|
|
2185
|
+
animal_lookup_type = AnimalType.poultry
|
|
2186
|
+
else:
|
|
2187
|
+
# Other animals have a value for animal group (Horses, Goats, etc.)
|
|
2188
|
+
animal_lookup_type = animal_type
|
|
2189
|
+
|
|
2190
|
+
return ManureComposition(
|
|
2191
|
+
**HolosTables.Table_6_Manure_Types_And_Default_Composition.loc[(animal_lookup_type, manure_state_type)])
|
|
2192
|
+
|
|
2193
|
+
|
|
2194
|
+
def get_beef_and_dairy_cattle_coefficient_data(
|
|
2195
|
+
animal_type: str
|
|
2196
|
+
) -> AnimalCoefficientData:
|
|
2197
|
+
df = HolosTables.Table_16_Livestock_Coefficients_BeefAndDairy_Cattle_Provider
|
|
2198
|
+
|
|
2199
|
+
if animal_type in df.index:
|
|
2200
|
+
_df = df.loc[animal_type]
|
|
2201
|
+
res = AnimalCoefficientData(
|
|
2202
|
+
baseline_maintenance_coefficient=_df['BaselineMaintenanceCoefficient'],
|
|
2203
|
+
gain_coefficient=_df['GainCoefficient'],
|
|
2204
|
+
default_initial_weight=_df['DefaultInitialWeight'],
|
|
2205
|
+
default_final_weight=_df['DefaultFinalWeight'])
|
|
2206
|
+
else:
|
|
2207
|
+
res = AnimalCoefficientData()
|
|
2208
|
+
return res
|
|
2209
|
+
|
|
2210
|
+
|
|
2211
|
+
def get_beef_and_dairy_cattle_feeding_activity_coefficient(
|
|
2212
|
+
housing_type: HousingType
|
|
2213
|
+
) -> float:
|
|
2214
|
+
"""Returns the coefficient corresponding to animal’s feeding situation (Ca in IPCC's tables)
|
|
2215
|
+
|
|
2216
|
+
Args:
|
|
2217
|
+
housing_type: HousingType class instance
|
|
2218
|
+
|
|
2219
|
+
Returns:
|
|
2220
|
+
(MJ day-1 kg-1) coefficient corresponding to animal’s feeding situation (Ca)
|
|
2221
|
+
|
|
2222
|
+
References:
|
|
2223
|
+
Table 10.5 in https://www.ipcc-nggip.iges.or.jp/public/2006gl/pdf/4_Volume4/V4_10_Ch10_Livestock.pdf
|
|
2224
|
+
|
|
2225
|
+
Holos source code:
|
|
2226
|
+
https://github.com/holos-aafc/Holos/blob/a84060af0e699de25158a1a9030dc9d78edd0e00/H.Core/Providers/Animals/Table_17_Beef_Dairy_Cattle_Feeding_Activity_Coefficient_Provider.cs#L21
|
|
2227
|
+
"""
|
|
2228
|
+
match housing_type:
|
|
2229
|
+
case HousingType.housed_in_barn | HousingType.confined | HousingType.confined_no_barn:
|
|
2230
|
+
res = 0
|
|
2231
|
+
|
|
2232
|
+
case HousingType.pasture | HousingType.flat_pasture | HousingType.enclosed_pasture:
|
|
2233
|
+
res = 0.17
|
|
2234
|
+
|
|
2235
|
+
case HousingType.open_range_or_hills:
|
|
2236
|
+
res = 0.36
|
|
2237
|
+
|
|
2238
|
+
case _:
|
|
2239
|
+
res = 0
|
|
2240
|
+
|
|
2241
|
+
return res
|
|
2242
|
+
|
|
2243
|
+
|
|
2244
|
+
def get_average_milk_production_for_dairy_cows_value(
|
|
2245
|
+
year: int,
|
|
2246
|
+
province: CanadianProvince
|
|
2247
|
+
):
|
|
2248
|
+
"""returns the average milk production value for a given Canadian Province.
|
|
2249
|
+
|
|
2250
|
+
Args:
|
|
2251
|
+
year: year for which the average milk production will be returned
|
|
2252
|
+
province: Canadian Province object
|
|
2253
|
+
|
|
2254
|
+
Returns:
|
|
2255
|
+
(kg head-1 day-1): the average milk production value
|
|
2256
|
+
|
|
2257
|
+
References:
|
|
2258
|
+
Holos source code: https://github.com/holos-aafc/Holos/blob/396f1ab9bc7247e6d78766f9445c14d2eb7c0d9d/H.Core/Providers/Animals/Table_21_Average_Milk_Production_Dairy_Cows_Provider.cs#L56
|
|
2259
|
+
"""
|
|
2260
|
+
df = HolosTables.Table_21_Average_Milk_Production_For_Dairy_Cows_By_Province
|
|
2261
|
+
year_min = min(df.index)
|
|
2262
|
+
year_max = max(df.index)
|
|
2263
|
+
|
|
2264
|
+
df = df.merge(DataFrame(index=range(year_min, year_max + 1)), right_index=True, left_index=True, how="right")
|
|
2265
|
+
df.interpolate(method="linear", inplace=True)
|
|
2266
|
+
|
|
2267
|
+
return df.loc[max(year_min, min(year_max, year)), province.value.abbreviation]
|
|
2268
|
+
|
|
2269
|
+
|
|
2270
|
+
def read_table_6():
|
|
2271
|
+
manure_composition_data = read_holos_resource_table(
|
|
2272
|
+
path_file=PathsHolosResources.Table_6_Manure_Types_And_Default_Composition)
|
|
2273
|
+
manure_composition_data['animal_type'] = manure_composition_data['animal_type'].apply(
|
|
2274
|
+
lambda x: convert_animal_type_name(name=x))
|
|
2275
|
+
manure_composition_data['manure_state_type'] = manure_composition_data['manure_state_type'].apply(
|
|
2276
|
+
lambda x: convert_manure_state_type_name(name=x))
|
|
2277
|
+
return manure_composition_data.set_index(['animal_type', 'manure_state_type'])
|
|
2278
|
+
|
|
2279
|
+
|
|
2280
|
+
def read_table_29():
|
|
2281
|
+
excretion_rates = read_holos_resource_table(
|
|
2282
|
+
path_file=PathsHolosResources.Table_29_Percentage_Total_Manure_Produced_In_Systems)
|
|
2283
|
+
excretion_rates.index = excretion_rates.pop('Animal group').apply(lambda x: convert_animal_type_name(name=x))
|
|
2284
|
+
return excretion_rates
|
|
2285
|
+
|
|
2286
|
+
|
|
2287
|
+
class HolosTables:
|
|
2288
|
+
Table_6_Manure_Types_And_Default_Composition: DataFrame = read_table_6()
|
|
2289
|
+
Table_16_Livestock_Coefficients_BeefAndDairy_Cattle_Provider = read_holos_resource_table(
|
|
2290
|
+
path_file=PathsHolosResources.Table_16_Livestock_Coefficients_BeefAndDairy_Cattle_Provider,
|
|
2291
|
+
index_col="AnimalType")
|
|
2292
|
+
Table_21_Average_Milk_Production_For_Dairy_Cows_By_Province = utils.read_holos_resource_table(
|
|
2293
|
+
path_file=PathsHolosResources.Table_21_Average_Milk_Production_For_Dairy_Cows_By_Province,
|
|
2294
|
+
index_col='Year')
|
|
2295
|
+
Table_29_Percentage_Total_Manure_Produced_In_Systems = read_table_29()
|
|
2296
|
+
Table_30_Default_Bedding_Material_Composition_Provider = read_holos_resource_table(
|
|
2297
|
+
path_file=PathsHolosResources.Table_30_Default_Bedding_Material_Composition_Provider)
|
|
2298
|
+
Table_61_Fractions_of_dairy_cattle_N_volatilized = read_holos_resource_table(
|
|
2299
|
+
path_file=PathsHolosResources.Table_61_Fractions_of_dairy_cattle_N_volatilized)
|
|
2300
|
+
Table_62_Fractions_of_swine_N_volatilized = read_holos_resource_table(
|
|
2301
|
+
path_file=PathsHolosResources.Table_62_Fractions_of_swine_N_volatilized)
|