hestia-earth-models 0.57.2__py3-none-any.whl → 0.59.0__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/cycle/aboveGroundCropResidueTotal.py +17 -12
- hestia_earth/models/cycle/excretaKgMass.py +4 -5
- hestia_earth/models/cycle/excretaKgN.py +4 -5
- hestia_earth/models/cycle/excretaKgVs.py +4 -5
- hestia_earth/models/cycle/inorganicFertiliser.py +2 -2
- hestia_earth/models/cycle/{irrigated.py → irrigatedTypeUnspecified.py} +4 -4
- hestia_earth/models/cycle/liveAnimal.py +9 -11
- hestia_earth/models/cycle/milkYield.py +154 -0
- hestia_earth/models/cycle/residueIncorporated.py +1 -1
- hestia_earth/models/cycle/utils.py +6 -0
- hestia_earth/models/emepEea2019/nh3ToAirInorganicFertiliser.py +3 -3
- hestia_earth/models/faostat2018/seed.py +2 -3
- hestia_earth/models/geospatialDatabase/clayContent.py +17 -4
- hestia_earth/models/geospatialDatabase/sandContent.py +17 -4
- hestia_earth/models/geospatialDatabase/siltContent.py +2 -2
- hestia_earth/models/impact_assessment/irrigated.py +0 -3
- hestia_earth/models/ipcc2006/co2ToAirOrganicSoilCultivation.py +2 -2
- hestia_earth/models/ipcc2006/n2OToAirCropResidueDecompositionIndirect.py +2 -2
- hestia_earth/models/ipcc2006/n2OToAirExcretaDirect.py +1 -1
- hestia_earth/models/ipcc2006/n2OToAirExcretaIndirect.py +8 -4
- hestia_earth/models/ipcc2006/n2OToAirInorganicFertiliserDirect.py +4 -1
- hestia_earth/models/ipcc2006/n2OToAirInorganicFertiliserIndirect.py +1 -1
- hestia_earth/models/ipcc2006/n2OToAirOrganicFertiliserDirect.py +1 -1
- hestia_earth/models/ipcc2006/n2OToAirOrganicFertiliserIndirect.py +1 -1
- hestia_earth/models/ipcc2006/utils.py +11 -8
- hestia_earth/models/ipcc2019/ch4ToAirEntericFermentation.py +4 -4
- hestia_earth/models/ipcc2019/ch4ToAirFloodedRice.py +16 -7
- hestia_earth/models/ipcc2019/co2ToAirSoilCarbonStockChangeManagementChange.py +759 -0
- hestia_earth/models/ipcc2019/croppingDuration.py +12 -6
- hestia_earth/models/ipcc2019/n2OToAirCropResidueDecompositionDirect.py +5 -52
- hestia_earth/models/ipcc2019/n2OToAirInorganicFertiliserDirect.py +104 -0
- hestia_earth/models/ipcc2019/n2OToAirInorganicFertiliserIndirect.py +1 -1
- hestia_earth/models/ipcc2019/n2OToAirOrganicFertiliserDirect.py +105 -0
- hestia_earth/models/ipcc2019/n2OToAirOrganicFertiliserIndirect.py +1 -1
- hestia_earth/models/ipcc2019/no3ToGroundwaterCropResidueDecomposition.py +1 -1
- hestia_earth/models/ipcc2019/no3ToGroundwaterExcreta.py +1 -1
- hestia_earth/models/ipcc2019/no3ToGroundwaterInorganicFertiliser.py +1 -1
- hestia_earth/models/ipcc2019/no3ToGroundwaterOrganicFertiliser.py +1 -1
- hestia_earth/models/ipcc2019/organicCarbonPerHa.py +1088 -1268
- hestia_earth/models/ipcc2019/pastureGrass.py +4 -4
- hestia_earth/models/ipcc2019/utils.py +102 -1
- hestia_earth/models/koble2014/aboveGroundCropResidue.py +15 -17
- hestia_earth/models/koble2014/cropResidueManagement.py +2 -2
- hestia_earth/models/koble2014/utils.py +19 -3
- hestia_earth/models/linkedImpactAssessment/__init__.py +4 -2
- hestia_earth/models/log.py +15 -3
- hestia_earth/models/mocking/search-results.json +184 -118
- hestia_earth/models/pooreNemecek2018/excretaKgN.py +6 -7
- hestia_earth/models/pooreNemecek2018/excretaKgVs.py +7 -6
- hestia_earth/models/pooreNemecek2018/no3ToGroundwaterCropResidueDecomposition.py +3 -2
- hestia_earth/models/pooreNemecek2018/no3ToGroundwaterExcreta.py +3 -2
- hestia_earth/models/pooreNemecek2018/no3ToGroundwaterInorganicFertiliser.py +3 -2
- hestia_earth/models/pooreNemecek2018/saplings.py +0 -1
- hestia_earth/models/site/management.py +168 -0
- hestia_earth/models/site/organicCarbonPerHa.py +251 -89
- hestia_earth/models/stehfestBouwman2006/n2OToAirCropResidueDecompositionDirect.py +3 -2
- hestia_earth/models/stehfestBouwman2006/n2OToAirExcretaDirect.py +3 -2
- hestia_earth/models/stehfestBouwman2006/n2OToAirInorganicFertiliserDirect.py +3 -2
- hestia_earth/models/stehfestBouwman2006/n2OToAirOrganicFertiliserDirect.py +3 -2
- hestia_earth/models/stehfestBouwman2006/noxToAirCropResidueDecomposition.py +3 -2
- hestia_earth/models/stehfestBouwman2006/noxToAirExcreta.py +3 -2
- hestia_earth/models/stehfestBouwman2006/noxToAirInorganicFertiliser.py +3 -2
- hestia_earth/models/stehfestBouwman2006/noxToAirOrganicFertiliser.py +3 -2
- hestia_earth/models/stehfestBouwman2006GisImplementation/noxToAirCropResidueDecomposition.py +3 -2
- hestia_earth/models/stehfestBouwman2006GisImplementation/noxToAirExcreta.py +3 -2
- hestia_earth/models/stehfestBouwman2006GisImplementation/noxToAirInorganicFertiliser.py +3 -2
- hestia_earth/models/stehfestBouwman2006GisImplementation/noxToAirOrganicFertiliser.py +3 -2
- hestia_earth/models/utils/aggregated.py +1 -0
- hestia_earth/models/utils/blank_node.py +394 -72
- hestia_earth/models/utils/cropResidue.py +13 -0
- hestia_earth/models/utils/cycle.py +18 -9
- hestia_earth/models/utils/measurement.py +1 -1
- hestia_earth/models/utils/property.py +4 -4
- hestia_earth/models/utils/term.py +48 -3
- hestia_earth/models/version.py +1 -1
- {hestia_earth_models-0.57.2.dist-info → hestia_earth_models-0.59.0.dist-info}/METADATA +5 -9
- {hestia_earth_models-0.57.2.dist-info → hestia_earth_models-0.59.0.dist-info}/RECORD +109 -97
- {hestia_earth_models-0.57.2.dist-info → hestia_earth_models-0.59.0.dist-info}/WHEEL +1 -1
- tests/models/cycle/animal/input/test_hestiaAggregatedData.py +2 -14
- tests/models/cycle/input/test_hestiaAggregatedData.py +4 -16
- tests/models/cycle/test_coldCarcassWeightPerHead.py +1 -1
- tests/models/cycle/test_coldDressedCarcassWeightPerHead.py +1 -1
- tests/models/cycle/{test_irrigated.py → test_irrigatedTypeUnspecified.py} +1 -1
- tests/models/cycle/test_milkYield.py +58 -0
- tests/models/cycle/test_readyToCookWeightPerHead.py +1 -1
- tests/models/emepEea2019/test_nh3ToAirInorganicFertiliser.py +1 -1
- tests/models/geospatialDatabase/test_clayContent.py +9 -3
- tests/models/geospatialDatabase/test_sandContent.py +9 -3
- tests/models/ipcc2006/test_n2OToAirExcretaDirect.py +7 -2
- tests/models/ipcc2006/test_n2OToAirExcretaIndirect.py +1 -1
- tests/models/ipcc2006/test_n2OToAirInorganicFertiliserDirect.py +7 -2
- tests/models/ipcc2006/test_n2OToAirInorganicFertiliserIndirect.py +7 -2
- tests/models/ipcc2006/test_n2OToAirOrganicFertiliserDirect.py +7 -2
- tests/models/ipcc2006/test_n2OToAirOrganicFertiliserIndirect.py +7 -2
- tests/models/ipcc2019/test_ch4ToAirEntericFermentation.py +1 -1
- tests/models/ipcc2019/test_co2ToAirSoilCarbonStockChangeManagementChange.py +228 -0
- tests/models/ipcc2019/test_n2OToAirInorganicFertiliserDirect.py +74 -0
- tests/models/ipcc2019/test_n2OToAirOrganicFertiliserDirect.py +74 -0
- tests/models/ipcc2019/test_organicCarbonPerHa.py +303 -1044
- tests/models/koble2014/test_residueBurnt.py +1 -2
- tests/models/koble2014/test_residueLeftOnField.py +1 -2
- tests/models/koble2014/test_residueRemoved.py +1 -2
- tests/models/koble2014/test_utils.py +52 -0
- tests/models/site/test_management.py +117 -0
- tests/models/site/test_organicCarbonPerHa.py +51 -5
- tests/models/utils/test_blank_node.py +230 -34
- tests/models/utils/test_term.py +17 -3
- {hestia_earth_models-0.57.2.dist-info → hestia_earth_models-0.59.0.dist-info}/LICENSE +0 -0
- {hestia_earth_models-0.57.2.dist-info → hestia_earth_models-0.59.0.dist-info}/top_level.txt +0 -0
|
@@ -96,7 +96,6 @@ LOOKUPS = {
|
|
|
96
96
|
"liveAquaticSpecies": ["excretaKgVsTermId", "allowedExcretaKgVsTermIds"]
|
|
97
97
|
}
|
|
98
98
|
MODEL_KEY = 'excretaKgVs'
|
|
99
|
-
MODEL_LOG = '/'.join([MODEL, MODEL_KEY])
|
|
100
99
|
|
|
101
100
|
Conv_AQ_CLW_CO2CR = 1
|
|
102
101
|
Conv_AQ_CLW_CExcr = 0.5
|
|
@@ -121,7 +120,9 @@ def _run(excreta_product: dict, mass_balance_items: list, inputs_c: float, alter
|
|
|
121
120
|
|
|
122
121
|
def _get_carbonContent(cycle: dict):
|
|
123
122
|
primary_prod = find_primary_product(cycle) or {}
|
|
124
|
-
return safe_parse_float(
|
|
123
|
+
return safe_parse_float(
|
|
124
|
+
get_lookup_value(primary_prod.get('term', {}), 'carbonContent', model=MODEL, model_key=MODEL_KEY)
|
|
125
|
+
) / 100
|
|
125
126
|
|
|
126
127
|
|
|
127
128
|
def _get_conv_aq_ocsed(siteType: str):
|
|
@@ -146,7 +147,7 @@ def _should_run(cycle: dict):
|
|
|
146
147
|
carbonContent = _get_carbonContent(cycle)
|
|
147
148
|
|
|
148
149
|
inputs_feed = get_feed_inputs(cycle)
|
|
149
|
-
inputs_c = convert_to_carbon(cycle,
|
|
150
|
+
inputs_c = convert_to_carbon(cycle, MODEL, excreta_term_id, inputs_feed, model_key=MODEL_KEY)
|
|
150
151
|
|
|
151
152
|
practices = cycle.get('practices', [])
|
|
152
153
|
tsy = list_sum(find_term_match(practices, 'yieldOfPrimaryAquacultureProductLiveweightPerM2').get('value', []))
|
|
@@ -162,7 +163,7 @@ def _should_run(cycle: dict):
|
|
|
162
163
|
excretaKgN = list_sum(excreta_n_product.get('value', [0]))
|
|
163
164
|
vsc = get_node_property(excreta_n_product, 'volatileSolidsContent').get('value', 0)
|
|
164
165
|
|
|
165
|
-
logRequirements(cycle, model=
|
|
166
|
+
logRequirements(cycle, model=MODEL, term=excreta_term_id, model_key=MODEL_KEY,
|
|
166
167
|
is_animalFeed_complete=is_animalFeed_complete,
|
|
167
168
|
is_product_complete=is_product_complete,
|
|
168
169
|
aqocsed=aqocsed,
|
|
@@ -187,8 +188,8 @@ def _should_run(cycle: dict):
|
|
|
187
188
|
])
|
|
188
189
|
# only log if the excreta term does not exist to avoid showing failure when it already exists
|
|
189
190
|
if should_add_product:
|
|
190
|
-
logShouldRun(cycle,
|
|
191
|
-
logShouldRun(cycle,
|
|
191
|
+
logShouldRun(cycle, MODEL, excreta_term_id, should_run, model_key=MODEL_KEY)
|
|
192
|
+
logShouldRun(cycle, MODEL, None, should_run)
|
|
192
193
|
return should_run, excreta_product, mass_balance_items, inputs_c, alternate_items
|
|
193
194
|
|
|
194
195
|
|
|
@@ -49,9 +49,10 @@ def _emission(value: float):
|
|
|
49
49
|
def _run(cycle: dict, N_total: float, content_list_of_items: list):
|
|
50
50
|
no3ToGroundwaterSoilFlux = _get_value(cycle, N_total, content_list_of_items, TERM_ID)
|
|
51
51
|
N_crop_residue = get_crop_residue_decomposition_N_total(cycle)
|
|
52
|
-
|
|
52
|
+
value = N_crop_residue / N_total * no3ToGroundwaterSoilFlux if all([
|
|
53
53
|
N_crop_residue, N_total
|
|
54
|
-
]) else 0
|
|
54
|
+
]) else 0
|
|
55
|
+
return [_emission(value)]
|
|
55
56
|
|
|
56
57
|
|
|
57
58
|
def run(cycle: dict):
|
|
@@ -54,9 +54,10 @@ def _emission(value: float):
|
|
|
54
54
|
def _run(cycle: dict, N_total: float, content_list_of_items: list):
|
|
55
55
|
no3ToGroundwaterSoilFlux = _get_value(cycle, N_total, content_list_of_items, TERM_ID)
|
|
56
56
|
N_excreta = get_excreta_N_total(cycle)
|
|
57
|
-
|
|
57
|
+
value = N_excreta / N_total * no3ToGroundwaterSoilFlux if all([
|
|
58
58
|
N_excreta, N_total
|
|
59
|
-
]) else 0
|
|
59
|
+
]) else 0
|
|
60
|
+
return [_emission(value)]
|
|
60
61
|
|
|
61
62
|
|
|
62
63
|
def run(cycle: dict):
|
|
@@ -49,9 +49,10 @@ def _emission(value: float):
|
|
|
49
49
|
def _run(cycle: dict, N_total: float, content_list_of_items: list):
|
|
50
50
|
no3ToGroundwaterSoilFlux = _get_value(cycle, N_total, content_list_of_items, TERM_ID)
|
|
51
51
|
N_inorganic_fertiliser = get_inorganic_fertiliser_N_total(cycle)
|
|
52
|
-
|
|
52
|
+
value = N_inorganic_fertiliser / N_total * no3ToGroundwaterSoilFlux if all([
|
|
53
53
|
N_inorganic_fertiliser, N_total
|
|
54
|
-
]) else 0
|
|
54
|
+
]) else 0
|
|
55
|
+
return [_emission(value)]
|
|
55
56
|
|
|
56
57
|
|
|
57
58
|
def run(cycle: dict):
|
|
@@ -12,7 +12,6 @@ REQUIREMENTS = {
|
|
|
12
12
|
"Cycle": {
|
|
13
13
|
"completeness.other": "False",
|
|
14
14
|
"products": [{"@type": "Product", "value": "", "term.termType": "crop"}],
|
|
15
|
-
"site": {"@type": "Site", "siteType": ["cropland", "permanent pasture"]},
|
|
16
15
|
"practices": [{"@type": "Practice", "value": "", "term.@id": "plantationLifespan"}]
|
|
17
16
|
}
|
|
18
17
|
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Management node with data gap-filled data from cycles.
|
|
3
|
+
"""
|
|
4
|
+
from typing import List
|
|
5
|
+
from functools import reduce
|
|
6
|
+
from hestia_earth.schema import SchemaType, TermTermType
|
|
7
|
+
from hestia_earth.utils.api import download_hestia
|
|
8
|
+
from hestia_earth.utils.model import filter_list_term_type, linked_node
|
|
9
|
+
from hestia_earth.utils.tools import flatten
|
|
10
|
+
|
|
11
|
+
from hestia_earth.models.log import logRequirements, logShouldRun, log_blank_nodes_id
|
|
12
|
+
from hestia_earth.models.utils.site import related_cycles
|
|
13
|
+
from hestia_earth.models.utils.term import get_lookup_value
|
|
14
|
+
from hestia_earth.models.utils.blank_node import get_node_value
|
|
15
|
+
from . import MODEL
|
|
16
|
+
|
|
17
|
+
REQUIREMENTS = {
|
|
18
|
+
"Site": {
|
|
19
|
+
"related": {
|
|
20
|
+
"Cycle": [{
|
|
21
|
+
"@type": "Cycle",
|
|
22
|
+
"startDate": "",
|
|
23
|
+
"endDate": "",
|
|
24
|
+
"products": [
|
|
25
|
+
{
|
|
26
|
+
"@type": "Product",
|
|
27
|
+
"term.termType": ["crop", "forage", "landCover"]
|
|
28
|
+
}
|
|
29
|
+
],
|
|
30
|
+
"practices": [
|
|
31
|
+
{
|
|
32
|
+
"term.termType": [
|
|
33
|
+
"waterRegime",
|
|
34
|
+
"tillage",
|
|
35
|
+
"cropResidueManagement",
|
|
36
|
+
"landUseManagement"
|
|
37
|
+
],
|
|
38
|
+
"value": ""
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
}]
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
RETURNS = {
|
|
46
|
+
"Management": [{
|
|
47
|
+
"@type": "Management",
|
|
48
|
+
"term.termType": [
|
|
49
|
+
"landCover", "waterRegime", "tillage", "cropResidueManagement", "landUseManagement"
|
|
50
|
+
],
|
|
51
|
+
"value": "",
|
|
52
|
+
"endDate": "",
|
|
53
|
+
"startDate": ""
|
|
54
|
+
}]
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
MODEL_KEY = 'management'
|
|
58
|
+
LAND_COVER_KEY = 'landCoverId'
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def management(data: dict):
|
|
62
|
+
node = {'@type': SchemaType.MANAGEMENT.value}
|
|
63
|
+
return node | data
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def _extract_node_value(node: dict) -> dict:
|
|
67
|
+
return node | {'value': get_node_value(node)}
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def _include(value: dict, keys: list): return {k: v for k, v in value.items() if k in keys}
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def _include_start_end(cycle: dict, values: list):
|
|
74
|
+
return [(_include(cycle, ['startDate', 'endDate']) | v) for v in values]
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def _copy_item_if_exists(source: dict, keys: List[str] = [], dest: dict = {}) -> dict:
|
|
78
|
+
return reduce(lambda p, c: p | ({c: source[c]} if c in source else {}), keys, dest)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _get_landCover_term_id(product: dict) -> str:
|
|
82
|
+
value = get_lookup_value(product.get('term', {}), LAND_COVER_KEY, model=MODEL, model_key=LAND_COVER_KEY)
|
|
83
|
+
# TODO: what should happen when there are multiple values?
|
|
84
|
+
return value.split(';')[0] if value else None
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def _get_items_with_relevant_term_type(cycles: List[dict], item_name: str, relevant_values: list):
|
|
88
|
+
"""Get items from the list of cycles with any of the relevant values. Also adds dates if missing."""
|
|
89
|
+
return flatten(
|
|
90
|
+
[
|
|
91
|
+
_include_start_end(
|
|
92
|
+
cycle=cycle,
|
|
93
|
+
values=filter_list_term_type(cycle.get(item_name, []), relevant_values)
|
|
94
|
+
) for cycle in cycles
|
|
95
|
+
]
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def should_run(site: dict):
|
|
100
|
+
# Only get related cycles once.
|
|
101
|
+
cycles = related_cycles(site.get("@id"))
|
|
102
|
+
|
|
103
|
+
products_land_cover = [
|
|
104
|
+
_extract_node_value(
|
|
105
|
+
_include(
|
|
106
|
+
value=product,
|
|
107
|
+
keys=["term", "value", "startDate", "endDate", "properties"]
|
|
108
|
+
)
|
|
109
|
+
) for product in _get_items_with_relevant_term_type(
|
|
110
|
+
cycles=cycles,
|
|
111
|
+
item_name="products",
|
|
112
|
+
relevant_values=[TermTermType.LANDCOVER]
|
|
113
|
+
)
|
|
114
|
+
]
|
|
115
|
+
|
|
116
|
+
products_crop_forage = _get_items_with_relevant_term_type(
|
|
117
|
+
cycles=cycles,
|
|
118
|
+
item_name="products",
|
|
119
|
+
relevant_values=[TermTermType.CROP, TermTermType.FORAGE]
|
|
120
|
+
)
|
|
121
|
+
products_crop_forage = [
|
|
122
|
+
_copy_item_if_exists(
|
|
123
|
+
source=product,
|
|
124
|
+
keys=["startDate", "endDate", "properties"],
|
|
125
|
+
dest={
|
|
126
|
+
"term": linked_node(download_hestia(_get_landCover_term_id(product))),
|
|
127
|
+
"value": 100
|
|
128
|
+
}
|
|
129
|
+
)
|
|
130
|
+
for product in list(filter(_get_landCover_term_id, products_crop_forage))
|
|
131
|
+
]
|
|
132
|
+
|
|
133
|
+
practices = [
|
|
134
|
+
_extract_node_value(
|
|
135
|
+
_include(
|
|
136
|
+
value=practice,
|
|
137
|
+
keys=["term", "value", "startDate", "endDate"]
|
|
138
|
+
)
|
|
139
|
+
) for practice in _get_items_with_relevant_term_type(
|
|
140
|
+
cycles=cycles,
|
|
141
|
+
item_name="practices",
|
|
142
|
+
relevant_values=[
|
|
143
|
+
TermTermType.WATERREGIME,
|
|
144
|
+
TermTermType.TILLAGE,
|
|
145
|
+
TermTermType.CROPRESIDUEMANAGEMENT,
|
|
146
|
+
TermTermType.LANDUSEMANAGEMENT
|
|
147
|
+
]
|
|
148
|
+
)
|
|
149
|
+
]
|
|
150
|
+
|
|
151
|
+
logRequirements(
|
|
152
|
+
site,
|
|
153
|
+
model=MODEL,
|
|
154
|
+
term=None,
|
|
155
|
+
model_key=MODEL_KEY,
|
|
156
|
+
products_crop_forage_ids=log_blank_nodes_id(products_crop_forage),
|
|
157
|
+
products_land_cover_ids=log_blank_nodes_id(products_land_cover),
|
|
158
|
+
practice_ids=log_blank_nodes_id(practices)
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
_should_run = any(products_crop_forage + products_land_cover + practices)
|
|
162
|
+
logShouldRun(site, MODEL, None, should_run=_should_run, model_key=MODEL_KEY)
|
|
163
|
+
return _should_run, products_crop_forage + products_land_cover, practices
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def run(site: dict):
|
|
167
|
+
_should_run, products, practices = should_run(site)
|
|
168
|
+
return list(map(management, products + practices)) if _should_run else []
|