hestia-earth-models 0.64.2__py3-none-any.whl → 0.64.4__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 hestia-earth-models might be problematic. Click here for more details.
- hestia_earth/models/agribalyse2016/machineryInfrastructureDepreciatedAmountPerCycle.py +2 -2
- hestia_earth/models/cycle/animal/input/hestiaAggregatedData.py +5 -2
- hestia_earth/models/cycle/animal/input/properties.py +2 -1
- hestia_earth/models/cycle/animal/milkYield.py +2 -1
- hestia_earth/models/cycle/concentrateFeed.py +8 -8
- hestia_earth/models/cycle/cycleDuration.py +4 -5
- hestia_earth/models/cycle/siteDuration.py +15 -5
- hestia_earth/models/cycle/startDateDefinition.py +3 -4
- hestia_earth/models/cycle/stockingDensityAnimalHousingAverage.py +52 -0
- hestia_earth/models/fantkeEtAl2016/__init__.py +13 -0
- hestia_earth/models/fantkeEtAl2016/damageToHumanHealthParticulateMatterFormation.py +49 -0
- hestia_earth/models/frischknechtEtAl2000/__init__.py +13 -0
- hestia_earth/models/frischknechtEtAl2000/ionisingRadiationKbqU235Eq.py +90 -0
- hestia_earth/models/ipcc2019/aboveGroundBiomass.py +762 -0
- hestia_earth/models/ipcc2019/aboveGroundBiomass_utils.py +180 -0
- hestia_earth/models/ipcc2019/animal/liveweightGain.py +89 -0
- hestia_earth/models/ipcc2019/animal/liveweightPerHead.py +89 -0
- hestia_earth/models/ipcc2019/animal/pastureGrass.py +51 -42
- hestia_earth/models/ipcc2019/animal/utils.py +20 -0
- hestia_earth/models/ipcc2019/animal/weightAtMaturity.py +15 -19
- hestia_earth/models/ipcc2019/ch4ToAirExcreta.py +2 -2
- hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_1_utils.py +37 -50
- hestia_earth/models/ipcc2019/organicCarbonPerHa_utils.py +0 -19
- hestia_earth/models/ipcc2019/pastureGrass.py +44 -31
- hestia_earth/models/ipcc2019/pastureGrass_utils.py +38 -22
- hestia_earth/models/mocking/search-results.json +228 -228
- hestia_earth/models/poschEtAl2008/terrestrialEutrophicationPotentialAccumulatedExceedance.py +40 -0
- hestia_earth/models/site/soilMeasurement.py +2 -2
- hestia_earth/models/utils/blank_node.py +20 -1
- hestia_earth/models/utils/crop.py +4 -0
- hestia_earth/models/utils/ecoClimateZone.py +99 -0
- hestia_earth/models/utils/emission.py +6 -2
- hestia_earth/models/utils/impact_assessment.py +10 -5
- hestia_earth/models/utils/lookup.py +5 -3
- hestia_earth/models/utils/productivity.py +1 -1
- hestia_earth/models/utils/property.py +2 -2
- hestia_earth/models/version.py +1 -1
- {hestia_earth_models-0.64.2.dist-info → hestia_earth_models-0.64.4.dist-info}/METADATA +1 -1
- {hestia_earth_models-0.64.2.dist-info → hestia_earth_models-0.64.4.dist-info}/RECORD +57 -35
- tests/models/cycle/test_siteDuration.py +22 -0
- tests/models/cycle/test_stockingDensityAnimalHousingAverage.py +42 -0
- tests/models/fantkeEtAl2016/__init__.py +0 -0
- tests/models/fantkeEtAl2016/test_damageToHumanHealthParticulateMatterFormation.py +20 -0
- tests/models/frischknechtEtAl2000/__init__.py +0 -0
- tests/models/frischknechtEtAl2000/test_ionisingRadiationKbqU235Eq.py +70 -0
- tests/models/ipcc2019/animal/test_liveweightGain.py +20 -0
- tests/models/ipcc2019/animal/test_liveweightPerHead.py +20 -0
- tests/models/ipcc2019/animal/test_pastureGrass.py +1 -1
- tests/models/ipcc2019/test_aboveGroundBiomass.py +182 -0
- tests/models/ipcc2019/test_aboveGroundBiomass_utils.py +92 -0
- tests/models/ipcc2019/test_organicCarbonPerHa_tier_1_utils.py +3 -2
- tests/models/ipcc2019/test_pastureGrass.py +2 -2
- tests/models/poschEtAl2008/test_terrestrialEutrophicationPotentialAccumulatedExceedance.py +44 -0
- tests/models/utils/test_ecoClimateZone.py +152 -0
- {hestia_earth_models-0.64.2.dist-info → hestia_earth_models-0.64.4.dist-info}/LICENSE +0 -0
- {hestia_earth_models-0.64.2.dist-info → hestia_earth_models-0.64.4.dist-info}/WHEEL +0 -0
- {hestia_earth_models-0.64.2.dist-info → hestia_earth_models-0.64.4.dist-info}/top_level.txt +0 -0
|
@@ -26,15 +26,14 @@ from hestia_earth.models.utils.blank_node import (
|
|
|
26
26
|
cumulative_nodes_match, cumulative_nodes_lookup_match, cumulative_nodes_term_match,
|
|
27
27
|
node_lookup_match, node_term_match, group_nodes_by_year
|
|
28
28
|
)
|
|
29
|
+
from hestia_earth.models.utils.ecoClimateZone import EcoClimateZone, get_eco_climate_zone_value
|
|
29
30
|
from hestia_earth.models.utils.descriptive_stats import calc_descriptive_stats
|
|
30
31
|
from hestia_earth.models.utils.measurement import _new_measurement
|
|
31
32
|
from hestia_earth.models.utils.property import get_node_property
|
|
32
33
|
|
|
33
34
|
from .organicCarbonPerHa_utils import (
|
|
34
|
-
check_irrigation, DEPTH_LOWER, DEPTH_UPPER,
|
|
35
|
-
|
|
36
|
-
get_residue_removed_or_burnt_terms_with_cache,
|
|
37
|
-
get_upland_rice_land_cover_terms_with_cache,
|
|
35
|
+
check_irrigation, DEPTH_LOWER, DEPTH_UPPER, get_cover_crop_property_terms_with_cache,
|
|
36
|
+
get_residue_removed_or_burnt_terms_with_cache, get_upland_rice_land_cover_terms_with_cache,
|
|
38
37
|
IPCC_SOIL_CATEGORY_TO_SOIL_TYPE_LOOKUP_VALUE, IPCC_LAND_USE_CATEGORY_TO_LAND_COVER_LOOKUP_VALUE,
|
|
39
38
|
IPCC_MANAGEMENT_CATEGORY_TO_GRASSLAND_MANAGEMENT_TERM_ID,
|
|
40
39
|
IPCC_MANAGEMENT_CATEGORY_TO_TILLAGE_MANAGEMENT_LOOKUP_VALUE, IpccSoilCategory, IpccCarbonInputCategory,
|
|
@@ -175,15 +174,15 @@ _SOC_REFS = {
|
|
|
175
174
|
IpccSoilCategory.SANDY_SOILS: {
|
|
176
175
|
EcoClimateZone.WARM_TEMPERATE_MOIST: {"value": 36000, "uncertainty": 23, "observations": 39},
|
|
177
176
|
EcoClimateZone.WARM_TEMPERATE_DRY: {"value": 10000, "uncertainty": 5, "observations": 338},
|
|
178
|
-
EcoClimateZone.COOL_TEMPERATE_MOIST: {"value":
|
|
179
|
-
EcoClimateZone.COOL_TEMPERATE_DRY: {"value":
|
|
177
|
+
EcoClimateZone.COOL_TEMPERATE_MOIST: {"value": 51000, "uncertainty": 13, "observations": 126},
|
|
178
|
+
EcoClimateZone.COOL_TEMPERATE_DRY: {"value": 13000, "uncertainty": 33, "observations": 10},
|
|
180
179
|
EcoClimateZone.POLAR_MOIST: {"value": 27000, "uncertainty": 67, "observations": 18},
|
|
181
180
|
EcoClimateZone.POLAR_DRY: {"value": 27000, "uncertainty": 67, "observations": 18},
|
|
182
181
|
EcoClimateZone.BOREAL_MOIST: {"value": 10000, "uncertainty": 90},
|
|
183
182
|
EcoClimateZone.BOREAL_DRY: {"value": 10000, "uncertainty": 90},
|
|
184
183
|
EcoClimateZone.TROPICAL_MONTANE: {"value": 52000, "uncertainty": 34, "observations": 11},
|
|
185
184
|
EcoClimateZone.TROPICAL_WET: {"value": 46000, "uncertainty": 20, "observations": 43},
|
|
186
|
-
EcoClimateZone.TROPICAL_MOIST: {"value":
|
|
185
|
+
EcoClimateZone.TROPICAL_MOIST: {"value": 27000, "uncertainty": 12, "observations": 76},
|
|
187
186
|
EcoClimateZone.TROPICAL_DRY: {"value": 9000, "uncertainty": 9, "observations": 164}
|
|
188
187
|
},
|
|
189
188
|
IpccSoilCategory.SPODIC_SOILS: {
|
|
@@ -645,35 +644,48 @@ def should_run(site: dict) -> tuple[bool, dict, dict]:
|
|
|
645
644
|
Returns
|
|
646
645
|
-------
|
|
647
646
|
tuple[bool, dict, dict]
|
|
648
|
-
A tuple containing `(should_run_, inventory, kwargs)`.
|
|
647
|
+
A tuple containing `(should_run_, inventory, kwargs, logs)`.
|
|
649
648
|
"""
|
|
650
649
|
site_type = site.get("siteType", "")
|
|
651
650
|
management_nodes = site.get("management", [])
|
|
652
651
|
measurement_nodes = site.get("measurements", [])
|
|
653
652
|
|
|
653
|
+
eco_climate_zone = get_eco_climate_zone_value(site, as_enum=True)
|
|
654
|
+
ipcc_soil_category = _assign_ipcc_soil_category(measurement_nodes)
|
|
655
|
+
soc_ref = _get_soc_ref_preview(ipcc_soil_category, eco_climate_zone)
|
|
656
|
+
|
|
654
657
|
has_management = len(management_nodes) > 0
|
|
655
658
|
has_measurements = len(measurement_nodes) > 0
|
|
656
659
|
|
|
657
660
|
should_compile_inventory = all([
|
|
658
661
|
site_type in _VALID_SITE_TYPES,
|
|
662
|
+
eco_climate_zone not in _EXCLUDED_ECO_CLIMATE_ZONES,
|
|
663
|
+
soc_ref or -9999 > 0,
|
|
659
664
|
has_management,
|
|
660
665
|
has_measurements
|
|
661
666
|
])
|
|
662
667
|
|
|
663
|
-
inventory,
|
|
664
|
-
_compile_inventory(
|
|
665
|
-
|
|
668
|
+
inventory, inventory_logs = (
|
|
669
|
+
_compile_inventory(
|
|
670
|
+
site_type,
|
|
671
|
+
management_nodes,
|
|
672
|
+
ipcc_soil_category
|
|
673
|
+
) if should_compile_inventory else ({}, {})
|
|
666
674
|
)
|
|
667
|
-
kwargs["seed"] = gen_seed(site)
|
|
668
675
|
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
676
|
+
kwargs = {
|
|
677
|
+
"seed": gen_seed(site),
|
|
678
|
+
"eco_climate_zone": eco_climate_zone,
|
|
679
|
+
"ipcc_soil_category": ipcc_soil_category,
|
|
680
|
+
}
|
|
674
681
|
|
|
675
|
-
|
|
682
|
+
should_run_ = any(
|
|
683
|
+
year for year, group in inventory.items() if group.get(_InventoryKey.SHOULD_RUN)
|
|
684
|
+
)
|
|
685
|
+
|
|
686
|
+
logs = inventory_logs | {
|
|
676
687
|
"site_type": site_type,
|
|
688
|
+
"soc_ref": soc_ref,
|
|
677
689
|
"has_management": has_management,
|
|
678
690
|
"has_measurements": has_measurements,
|
|
679
691
|
"should_compile_inventory_tier_1": should_compile_inventory,
|
|
@@ -965,7 +977,7 @@ def _calc_soc_stocks(
|
|
|
965
977
|
|
|
966
978
|
|
|
967
979
|
def _compile_inventory(
|
|
968
|
-
site_type: str, management_nodes: list[dict],
|
|
980
|
+
site_type: str, management_nodes: list[dict], ipcc_soil_category: IpccSoilCategory
|
|
969
981
|
) -> tuple[dict, dict]:
|
|
970
982
|
"""
|
|
971
983
|
Builds an annual inventory of data and a dictionary of keyword arguments for the tier 1 model.
|
|
@@ -978,17 +990,14 @@ def _compile_inventory(
|
|
|
978
990
|
A valid [site type](https://www-staging.hestia.earth/schema/Site#siteType).
|
|
979
991
|
management_nodes : list[dict]
|
|
980
992
|
A list of [Management nodes](https://www-staging.hestia.earth/schema/Management).
|
|
981
|
-
|
|
982
|
-
|
|
993
|
+
ipcc_soil_category : IpccSoilCategory
|
|
994
|
+
The site's assigned IPCC soil category.
|
|
983
995
|
|
|
984
996
|
Returns
|
|
985
997
|
-------
|
|
986
998
|
tuple[dict, dict]
|
|
987
|
-
A tuple containing `(inventory,
|
|
999
|
+
A tuple containing `(inventory, logs)`.
|
|
988
1000
|
"""
|
|
989
|
-
eco_climate_zone = _get_eco_climate_zone(measurement_nodes)
|
|
990
|
-
ipcc_soil_category = _assign_ipcc_soil_category(measurement_nodes)
|
|
991
|
-
soc_ref = _get_soc_ref_preview(ipcc_soil_category, eco_climate_zone)
|
|
992
1001
|
grouped_management = group_nodes_by_year(management_nodes)
|
|
993
1002
|
|
|
994
1003
|
# If no `landCover` nodes in `site.management` use `site.siteType` to assign static `IpccLandUseCategory`.
|
|
@@ -1036,33 +1045,11 @@ def _compile_inventory(
|
|
|
1036
1045
|
}
|
|
1037
1046
|
|
|
1038
1047
|
inventory = merge(grouped_data, grouped_should_run)
|
|
1039
|
-
|
|
1040
|
-
"
|
|
1041
|
-
"ipcc_soil_category": ipcc_soil_category,
|
|
1042
|
-
"run_with_site_type": run_with_site_type,
|
|
1043
|
-
"soc_ref": soc_ref
|
|
1048
|
+
logs = {
|
|
1049
|
+
"run_with_site_type": run_with_site_type
|
|
1044
1050
|
}
|
|
1045
1051
|
|
|
1046
|
-
return inventory,
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
def _get_eco_climate_zone(measurement_nodes: list[dict]) -> Union[EcoClimateZone, None]:
|
|
1050
|
-
"""
|
|
1051
|
-
Get the eco-climate zone value from a list of Measurement nodes.
|
|
1052
|
-
|
|
1053
|
-
Parameters
|
|
1054
|
-
----------
|
|
1055
|
-
measurement_nodes : list[dict]
|
|
1056
|
-
A list of [Measurement nodes](https://www-staging.hestia.earth/schema/Measurement).
|
|
1057
|
-
|
|
1058
|
-
Returns
|
|
1059
|
-
-------
|
|
1060
|
-
EcoClimateZone | None
|
|
1061
|
-
The eco-climate zone value if found, otherwise `None`.
|
|
1062
|
-
"""
|
|
1063
|
-
eco_climate_zone = find_term_match(measurement_nodes, "ecoClimateZone")
|
|
1064
|
-
value = get_node_value(eco_climate_zone)
|
|
1065
|
-
return EcoClimateZone(value) if value else None
|
|
1052
|
+
return inventory, logs
|
|
1066
1053
|
|
|
1067
1054
|
|
|
1068
1055
|
def _assign_ipcc_soil_category(
|
|
@@ -43,25 +43,6 @@ def get_upland_rice_land_cover_terms_with_cache():
|
|
|
43
43
|
return lru_cache()(get_upland_rice_land_cover_terms)()
|
|
44
44
|
|
|
45
45
|
|
|
46
|
-
class EcoClimateZone(Enum):
|
|
47
|
-
"""
|
|
48
|
-
Enum representing eco-climate zones. The value of each member of the Enum correctly corresponds with the values of
|
|
49
|
-
`ecoClimateZone` term and the `ecoClimateZone-lookup.csv`.
|
|
50
|
-
"""
|
|
51
|
-
WARM_TEMPERATE_MOIST = 1
|
|
52
|
-
WARM_TEMPERATE_DRY = 2
|
|
53
|
-
COOL_TEMPERATE_MOIST = 3
|
|
54
|
-
COOL_TEMPERATE_DRY = 4
|
|
55
|
-
POLAR_MOIST = 5
|
|
56
|
-
POLAR_DRY = 6
|
|
57
|
-
BOREAL_MOIST = 7
|
|
58
|
-
BOREAL_DRY = 8
|
|
59
|
-
TROPICAL_MONTANE = 9
|
|
60
|
-
TROPICAL_WET = 10
|
|
61
|
-
TROPICAL_MOIST = 11
|
|
62
|
-
TROPICAL_DRY = 12
|
|
63
|
-
|
|
64
|
-
|
|
65
46
|
class IpccSoilCategory(Enum):
|
|
66
47
|
"""
|
|
67
48
|
Enum representing IPCC Soil Categories.
|
|
@@ -10,7 +10,7 @@ This version of the model will run at the Cycle level, if at least one Cycle Inp
|
|
|
10
10
|
"""
|
|
11
11
|
from hestia_earth.schema import TermTermType
|
|
12
12
|
from hestia_earth.utils.model import filter_list_term_type
|
|
13
|
-
from hestia_earth.utils.tools import list_sum
|
|
13
|
+
from hestia_earth.utils.tools import list_sum, non_empty_list
|
|
14
14
|
|
|
15
15
|
from hestia_earth.models.log import logRequirements, logShouldRun, log_as_table
|
|
16
16
|
from hestia_earth.models.utils.blank_node import lookups_logs, properties_logs
|
|
@@ -41,15 +41,22 @@ REQUIREMENTS = {
|
|
|
41
41
|
"@type": "Site",
|
|
42
42
|
"siteType": "permanent pasture"
|
|
43
43
|
},
|
|
44
|
-
"practices": [
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
44
|
+
"practices": [
|
|
45
|
+
{
|
|
46
|
+
"@type": "Practice",
|
|
47
|
+
"value": "",
|
|
48
|
+
"term.termType": "system"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"@type": "Practice",
|
|
52
|
+
"value": "",
|
|
53
|
+
"term.@id": "pastureGrass",
|
|
54
|
+
"key": {
|
|
55
|
+
"@type": "Term",
|
|
56
|
+
"term.termType": "landCover"
|
|
57
|
+
}
|
|
51
58
|
}
|
|
52
|
-
|
|
59
|
+
],
|
|
53
60
|
"inputs": [{
|
|
54
61
|
"@type": "Input",
|
|
55
62
|
"term.units": "kg",
|
|
@@ -142,7 +149,8 @@ LOOKUPS = {
|
|
|
142
149
|
RETURNS = {
|
|
143
150
|
"Input": [{
|
|
144
151
|
"term.termType": ["crop", "forage"],
|
|
145
|
-
"value": ""
|
|
152
|
+
"value": "",
|
|
153
|
+
"isAnimalFeed": "True"
|
|
146
154
|
}]
|
|
147
155
|
}
|
|
148
156
|
MODEL_KEY = 'pastureGrass'
|
|
@@ -151,6 +159,7 @@ MODEL_KEY = 'pastureGrass'
|
|
|
151
159
|
def _input(term_id: str, value: float):
|
|
152
160
|
node = _new_input(term_id, MODEL)
|
|
153
161
|
node['value'] = [value]
|
|
162
|
+
node['isAnimalFeed'] = True
|
|
154
163
|
return node
|
|
155
164
|
|
|
156
165
|
|
|
@@ -163,16 +172,14 @@ def calculate_NEwool(cycle: dict) -> float:
|
|
|
163
172
|
return sum([value * lookup_value for (value, lookup_value) in product_values])
|
|
164
173
|
|
|
165
174
|
|
|
166
|
-
def _run_practice(cycle: dict, meanDE: float, meanECHHV: float,
|
|
175
|
+
def _run_practice(cycle: dict, meanDE: float, meanECHHV: float, REM: float, REG: float, systems: list):
|
|
167
176
|
animals = get_animals_by_period(cycle)
|
|
168
|
-
REM = calculate_REM(meanDE)
|
|
169
|
-
REG = calculate_REG(meanDE)
|
|
170
177
|
NEwool = calculate_NEwool(cycle)
|
|
171
|
-
NEm_feed, NEg_feed = calculate_NEfeed(cycle)
|
|
178
|
+
NEm_feed, NEg_feed, log_feed = calculate_NEfeed(cycle)
|
|
172
179
|
|
|
173
180
|
animal_values = [{
|
|
174
|
-
'
|
|
175
|
-
} | get_animal_values(cycle, animal,
|
|
181
|
+
'id': animal.get('term', {}).get('@id')
|
|
182
|
+
} | get_animal_values(cycle, animal, systems) for animal in animals]
|
|
176
183
|
|
|
177
184
|
GE = (
|
|
178
185
|
calculate_GE(animal_values, REM, REG, NEwool, NEm_feed, NEg_feed) / (meanDE/100)
|
|
@@ -185,15 +192,11 @@ def _run_practice(cycle: dict, meanDE: float, meanECHHV: float, system: dict):
|
|
|
185
192
|
value = (GE / meanECHHV) * (list_sum(practice.get('value', [0])) / 100)
|
|
186
193
|
|
|
187
194
|
logs = log_as_table([v | {
|
|
188
|
-
'practiceKeyId': key_id,
|
|
189
|
-
'REM': REM,
|
|
190
|
-
'REG': REG,
|
|
191
195
|
'NEwool': NEwool,
|
|
192
|
-
'
|
|
193
|
-
'
|
|
194
|
-
'
|
|
195
|
-
'
|
|
196
|
-
'meanDE': meanDE
|
|
196
|
+
'total-feed-NEm': NEm_feed,
|
|
197
|
+
'total-feed-NEg': NEg_feed,
|
|
198
|
+
'practiceKeyId': key_id,
|
|
199
|
+
'GE': GE
|
|
197
200
|
} for v in animal_values])
|
|
198
201
|
animal_lookups = lookups_logs(MODEL, animals, LOOKUPS, model_key=MODEL_KEY, term=input_term_id)
|
|
199
202
|
animal_properties = properties_logs(animals, properties=[
|
|
@@ -207,15 +210,19 @@ def _run_practice(cycle: dict, meanDE: float, meanECHHV: float, system: dict):
|
|
|
207
210
|
'weightAtOneYear',
|
|
208
211
|
'weightAtSlaughter'
|
|
209
212
|
])
|
|
213
|
+
has_positive_feed_values = all([NEm_feed > 0, NEg_feed > 0])
|
|
210
214
|
|
|
211
215
|
logRequirements(cycle, model=MODEL, term=input_term_id, model_key=MODEL_KEY,
|
|
216
|
+
feed_logs=log_as_table(log_feed),
|
|
217
|
+
has_positive_feed_values=has_positive_feed_values,
|
|
212
218
|
animal_logs=logs,
|
|
213
219
|
animal_lookups=animal_lookups,
|
|
214
220
|
animal_properties=animal_properties)
|
|
215
221
|
|
|
216
|
-
|
|
222
|
+
should_run = all([has_positive_feed_values])
|
|
223
|
+
logShouldRun(cycle, MODEL, input_term_id, should_run, model_key=MODEL_KEY)
|
|
217
224
|
|
|
218
|
-
return _input(input_term_id, value)
|
|
225
|
+
return _input(input_term_id, value) if should_run else None
|
|
219
226
|
|
|
220
227
|
return run
|
|
221
228
|
|
|
@@ -231,6 +238,8 @@ def _should_run(cycle: dict, practices: dict):
|
|
|
231
238
|
|
|
232
239
|
meanDE = calculate_meanDE(practices)
|
|
233
240
|
meanECHHV = calculate_meanECHHV(practices)
|
|
241
|
+
REM = calculate_REM(meanDE)
|
|
242
|
+
REG = calculate_REG(meanDE)
|
|
234
243
|
|
|
235
244
|
should_run = all([
|
|
236
245
|
animalFeed_complete,
|
|
@@ -251,15 +260,19 @@ def _should_run(cycle: dict, practices: dict):
|
|
|
251
260
|
term_type_freshForage_incomplete=freshForage_incomplete,
|
|
252
261
|
has_cycle_inputs_feed=has_cycle_inputs_feed,
|
|
253
262
|
all_animals_have_value=all_animals_have_value,
|
|
254
|
-
|
|
255
|
-
|
|
263
|
+
grass_MeanDE=calculate_meanDE(practices, term=term_id),
|
|
264
|
+
grass_MeanECHHV=calculate_meanECHHV(practices, term=term_id),
|
|
265
|
+
grass_REM=REM,
|
|
266
|
+
grass_REG=REG)
|
|
256
267
|
|
|
257
268
|
logShouldRun(cycle, MODEL, term_id, should_run, model_key=MODEL_KEY)
|
|
258
269
|
|
|
259
|
-
return should_run, meanDE, meanECHHV,
|
|
270
|
+
return should_run, meanDE, meanECHHV, REM, REG, systems
|
|
260
271
|
|
|
261
272
|
|
|
262
273
|
def run(cycle: dict):
|
|
263
274
|
practices = list(filter(should_run_practice(cycle), cycle.get('practices', [])))
|
|
264
|
-
should_run, meanDE, meanECHHV,
|
|
265
|
-
return
|
|
275
|
+
should_run, meanDE, meanECHHV, REM, REG, systems = _should_run(cycle, practices)
|
|
276
|
+
return non_empty_list(
|
|
277
|
+
map(_run_practice(cycle, meanDE, meanECHHV, REM, REG, systems), practices)
|
|
278
|
+
) if should_run else []
|
|
@@ -25,12 +25,20 @@ def _get_grouping(animal: dict) -> str:
|
|
|
25
25
|
return get_lookup_value(term, 'ipcc2019AnimalTypeGrouping', model=MODEL, model_key=MODEL_KEY)
|
|
26
26
|
|
|
27
27
|
|
|
28
|
-
def _get_activityCoefficient(
|
|
28
|
+
def _get_activityCoefficient(animal: dict, systems: list) -> float:
|
|
29
29
|
term = animal.get('term', {})
|
|
30
30
|
term_id = term.get('@id')
|
|
31
|
-
system_id = system.get('term', {}).get('@id')
|
|
32
31
|
lookup = download_lookup('system-liveAnimal-activityCoefficient-ipcc2019.csv')
|
|
33
|
-
|
|
32
|
+
|
|
33
|
+
activityCoefficient = list_sum([
|
|
34
|
+
safe_parse_float(
|
|
35
|
+
get_table_value(lookup, 'termid', system.get('term', {}).get('@id'), column_name(term_id)),
|
|
36
|
+
0
|
|
37
|
+
) * list_sum(system.get('value', [0]))
|
|
38
|
+
for system in systems
|
|
39
|
+
]) / list_sum([
|
|
40
|
+
list_sum(system.get('value', [0])) for system in systems
|
|
41
|
+
])
|
|
34
42
|
|
|
35
43
|
return activityCoefficient
|
|
36
44
|
|
|
@@ -49,16 +57,16 @@ def _calculate_NEm(cycle: dict, animal: dict) -> float:
|
|
|
49
57
|
return NEm
|
|
50
58
|
|
|
51
59
|
|
|
52
|
-
def _calculate_NEa_cattleAndBuffalo(cycle: dict, animal: dict,
|
|
53
|
-
activityCoefficient = _get_activityCoefficient(
|
|
60
|
+
def _calculate_NEa_cattleAndBuffalo(cycle: dict, animal: dict, systems: list, NEm: float) -> float:
|
|
61
|
+
activityCoefficient = _get_activityCoefficient(animal, systems)
|
|
54
62
|
|
|
55
63
|
NEa = activityCoefficient * NEm
|
|
56
64
|
|
|
57
65
|
return NEa
|
|
58
66
|
|
|
59
67
|
|
|
60
|
-
def _calculate_NEa_sheepAndGoat(cycle: dict, animal: dict,
|
|
61
|
-
activityCoefficient = _get_activityCoefficient(
|
|
68
|
+
def _calculate_NEa_sheepAndGoat(cycle: dict, animal: dict, systems: list, _NEm: float) -> float:
|
|
69
|
+
activityCoefficient = _get_activityCoefficient(animal, systems)
|
|
62
70
|
|
|
63
71
|
liveweightPerHead = get_node_property(animal, 'liveweightPerHead', False).get('value', 0)
|
|
64
72
|
animal_value = animal.get('value', 0)
|
|
@@ -74,9 +82,9 @@ _NEa_BY_GROUPING = {
|
|
|
74
82
|
}
|
|
75
83
|
|
|
76
84
|
|
|
77
|
-
def _calculate_NEa(cycle: dict, animal: dict,
|
|
85
|
+
def _calculate_NEa(cycle: dict, animal: dict, systems: list, NEm: float) -> float:
|
|
78
86
|
grouping = _get_grouping(animal)
|
|
79
|
-
return _NEa_BY_GROUPING.get(grouping, lambda *args: 0)(cycle, animal,
|
|
87
|
+
return _NEa_BY_GROUPING.get(grouping, lambda *args: 0)(cycle, animal, systems, NEm)
|
|
80
88
|
|
|
81
89
|
|
|
82
90
|
def _calculate_NEl_cattleAndBuffalo(cycle: dict, animal: dict) -> float:
|
|
@@ -234,7 +242,7 @@ def _calculate_feed_meanDE(log_node: dict, input: dict) -> float:
|
|
|
234
242
|
debugValues(log_node, model=MODEL, term=term_id, model_key=MODEL_KEY,
|
|
235
243
|
energyContent=energyContent,
|
|
236
244
|
energyDigestibility=energyDigestibility,
|
|
237
|
-
|
|
245
|
+
feed_MeanDE=meanDE)
|
|
238
246
|
|
|
239
247
|
return meanDE
|
|
240
248
|
|
|
@@ -246,7 +254,7 @@ def _calculate_NEfeed_m(log_node: dict, input: dict, meanDE: float) -> float:
|
|
|
246
254
|
REm = calculate_REM(energyDigestibility * 100)
|
|
247
255
|
|
|
248
256
|
debugValues(log_node, model=MODEL, term=term_id, model_key=MODEL_KEY,
|
|
249
|
-
|
|
257
|
+
feed_REm=REm)
|
|
250
258
|
|
|
251
259
|
input_value = list_sum(input.get('value'))
|
|
252
260
|
return meanDE * REm * input_value
|
|
@@ -259,7 +267,7 @@ def _calculate_NEfeed_g(log_node: dict, input: dict, meanDE: float) -> float:
|
|
|
259
267
|
REg = calculate_REG(energyDigestibility * 100)
|
|
260
268
|
|
|
261
269
|
debugValues(log_node, model=MODEL, term=term_id, model_key=MODEL_KEY,
|
|
262
|
-
|
|
270
|
+
feed_REg=REg)
|
|
263
271
|
|
|
264
272
|
input_value = list_sum(input.get('value'))
|
|
265
273
|
return meanDE * REg * input_value
|
|
@@ -267,21 +275,29 @@ def _calculate_NEfeed_g(log_node: dict, input: dict, meanDE: float) -> float:
|
|
|
267
275
|
|
|
268
276
|
def calculate_NEfeed(node: dict) -> tuple:
|
|
269
277
|
inputs = get_feed_inputs(node)
|
|
278
|
+
|
|
270
279
|
# calculate meanDE for each input first
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
]
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
280
|
+
values = [
|
|
281
|
+
(i, {'id': i.get('term', {}).get('@id'), 'meanDE': _calculate_feed_meanDE(node, i)})
|
|
282
|
+
for i in inputs
|
|
283
|
+
]
|
|
284
|
+
values = [
|
|
285
|
+
value | {
|
|
286
|
+
'NEm': _calculate_NEfeed_m(node, input, value.get('meanDE')),
|
|
287
|
+
'NEg': _calculate_NEfeed_g(node, input, value.get('meanDE'))
|
|
288
|
+
}
|
|
289
|
+
for input, value in values
|
|
290
|
+
]
|
|
291
|
+
|
|
292
|
+
NEfeed_m = sum([value.get('NEm') for value in values]) if len(values) > 0 else 0
|
|
293
|
+
NEfeed_g = sum([value.get('NEg') for value in values]) if len(values) > 0 else 0
|
|
278
294
|
|
|
279
|
-
return (NEfeed_m, NEfeed_g)
|
|
295
|
+
return (NEfeed_m, NEfeed_g, values)
|
|
280
296
|
|
|
281
297
|
|
|
282
|
-
def get_animal_values(cycle: dict, animal: dict,
|
|
298
|
+
def get_animal_values(cycle: dict, animal: dict, systems: list) -> dict:
|
|
283
299
|
NEm = _calculate_NEm(cycle, animal)
|
|
284
|
-
NEa = _calculate_NEa(cycle, animal,
|
|
300
|
+
NEa = _calculate_NEa(cycle, animal, systems, NEm)
|
|
285
301
|
NEl = _calculate_NEl(cycle, animal)
|
|
286
302
|
NEwork = _calculate_NEwork(cycle, animal, NEm)
|
|
287
303
|
NEp = _calculate_NEp(cycle, animal, NEm)
|