hestia-earth-models 0.59.4__py3-none-any.whl → 0.59.6__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/animal/milkYield.py +86 -0
- hestia_earth/models/cycle/endDate.py +50 -0
- hestia_earth/models/cycle/inorganicFertiliser.py +3 -2
- hestia_earth/models/cycle/liveAnimal.py +3 -0
- hestia_earth/models/cycle/milkYield.py +8 -3
- hestia_earth/models/cycle/pre_checks/__init__.py +1 -2
- hestia_earth/models/cycle/startDate.py +42 -0
- hestia_earth/models/cycle/utils.py +1 -1
- hestia_earth/models/faostat2018/liveweightPerHead.py +77 -41
- hestia_earth/models/faostat2018/product/price.py +30 -55
- hestia_earth/models/faostat2018/utils.py +10 -2
- hestia_earth/models/geospatialDatabase/potentialEvapotranspirationLongTermAnnualMean.py +2 -2
- hestia_earth/models/geospatialDatabase/potentialEvapotranspirationMonthly.py +9 -8
- hestia_earth/models/geospatialDatabase/precipitationMonthly.py +10 -8
- hestia_earth/models/geospatialDatabase/temperatureAnnual.py +2 -5
- hestia_earth/models/geospatialDatabase/temperatureLongTermAnnualMean.py +2 -3
- hestia_earth/models/geospatialDatabase/temperatureMonthly.py +8 -8
- hestia_earth/models/geospatialDatabase/utils.py +6 -1
- hestia_earth/models/haversineFormula/transport/distance.py +6 -3
- hestia_earth/models/ipcc2006/n2OToAirInorganicFertiliserIndirect.py +1 -1
- hestia_earth/models/ipcc2019/organicCarbonPerHa.py +89 -114
- hestia_earth/models/ipcc2019/pastureGrass.py +2 -1
- hestia_earth/models/linkedImpactAssessment/__init__.py +78 -43
- hestia_earth/models/mocking/search-results.json +244 -271
- hestia_earth/models/schmidt2007/h2SToAirWasteTreatment.py +58 -0
- hestia_earth/models/schmidt2007/n2OToAirWasteTreatmentDirect.py +58 -0
- hestia_earth/models/schmidt2007/nh3ToAirWasteTreatment.py +58 -0
- hestia_earth/models/site/management.py +107 -12
- hestia_earth/models/site/soilMeasurement.py +9 -9
- hestia_earth/models/utils/__init__.py +4 -1
- hestia_earth/models/utils/animalProduct.py +6 -4
- hestia_earth/models/utils/blank_node.py +6 -5
- hestia_earth/models/utils/product.py +9 -1
- hestia_earth/models/utils/term.py +0 -23
- hestia_earth/models/version.py +1 -1
- {hestia_earth_models-0.59.4.dist-info → hestia_earth_models-0.59.6.dist-info}/METADATA +1 -1
- {hestia_earth_models-0.59.4.dist-info → hestia_earth_models-0.59.6.dist-info}/RECORD +53 -43
- tests/models/cycle/animal/test_milkYield.py +43 -0
- tests/models/cycle/test_endDate.py +24 -0
- tests/models/cycle/test_startDate.py +22 -0
- tests/models/faostat2018/product/test_price.py +25 -45
- tests/models/faostat2018/test_liveweightPerHead.py +106 -42
- tests/models/ipcc2019/test_organicCarbonPerHa.py +12 -18
- tests/models/schmidt2007/test_h2SToAirWasteTreatment.py +45 -0
- tests/models/schmidt2007/test_n2OToAirWasteTreatmentDirect.py +45 -0
- tests/models/schmidt2007/test_nh3ToAirWasteTreatment.py +45 -0
- tests/models/site/test_management.py +24 -3
- tests/models/site/test_soilMeasurement.py +40 -21
- tests/models/utils/test_blank_node.py +71 -3
- tests/models/utils/test_term.py +1 -8
- hestia_earth/models/cycle/pre_checks/startDate.py +0 -52
- tests/models/cycle/pre_checks/test_startDate.py +0 -44
- {hestia_earth_models-0.59.4.dist-info → hestia_earth_models-0.59.6.dist-info}/LICENSE +0 -0
- {hestia_earth_models-0.59.4.dist-info → hestia_earth_models-0.59.6.dist-info}/WHEEL +0 -0
- {hestia_earth_models-0.59.4.dist-info → hestia_earth_models-0.59.6.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
from hestia_earth.schema import EmissionMethodTier
|
|
2
|
+
from hestia_earth.utils.tools import list_sum
|
|
3
|
+
|
|
4
|
+
from hestia_earth.models.log import logRequirements, logShouldRun
|
|
5
|
+
from hestia_earth.models.utils.emission import _new_emission
|
|
6
|
+
from .utils import get_waste_values
|
|
7
|
+
from . import MODEL
|
|
8
|
+
|
|
9
|
+
REQUIREMENTS = {
|
|
10
|
+
"Cycle": {
|
|
11
|
+
"or": {
|
|
12
|
+
"product": [
|
|
13
|
+
{"@type": "Product", "value": "", "term.termType": "waste"}
|
|
14
|
+
],
|
|
15
|
+
"completeness.waste": ""
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
RETURNS = {
|
|
20
|
+
"Emission": [{
|
|
21
|
+
"value": "",
|
|
22
|
+
"methodTier": "tier 1"
|
|
23
|
+
}]
|
|
24
|
+
}
|
|
25
|
+
LOOKUPS = {
|
|
26
|
+
"waste": "h2SEfSchmidt2007"
|
|
27
|
+
}
|
|
28
|
+
TERM_ID = 'h2SToAirWasteTreatment'
|
|
29
|
+
TIER = EmissionMethodTier.TIER_1.value
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _emission(value: float):
|
|
33
|
+
emission = _new_emission(TERM_ID, MODEL)
|
|
34
|
+
emission['value'] = [value]
|
|
35
|
+
emission['methodTier'] = TIER
|
|
36
|
+
return emission
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _run(waste_values: list):
|
|
40
|
+
value = list_sum(waste_values)
|
|
41
|
+
return [_emission(value)]
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _should_run(cycle: dict):
|
|
45
|
+
waste_values = get_waste_values(TERM_ID, cycle, LOOKUPS['waste'])
|
|
46
|
+
has_waste = len(waste_values) > 0
|
|
47
|
+
|
|
48
|
+
logRequirements(cycle, model=MODEL, term=TERM_ID,
|
|
49
|
+
has_waste=has_waste)
|
|
50
|
+
|
|
51
|
+
should_run = any([has_waste])
|
|
52
|
+
logShouldRun(cycle, MODEL, TERM_ID, should_run, methodTier=TIER)
|
|
53
|
+
return should_run, waste_values
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def run(cycle: dict):
|
|
57
|
+
should_run, waste_values = _should_run(cycle)
|
|
58
|
+
return _run(waste_values) if should_run else []
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
from hestia_earth.schema import EmissionMethodTier
|
|
2
|
+
from hestia_earth.utils.tools import list_sum
|
|
3
|
+
|
|
4
|
+
from hestia_earth.models.log import logRequirements, logShouldRun
|
|
5
|
+
from hestia_earth.models.utils.emission import _new_emission
|
|
6
|
+
from .utils import get_waste_values
|
|
7
|
+
from . import MODEL
|
|
8
|
+
|
|
9
|
+
REQUIREMENTS = {
|
|
10
|
+
"Cycle": {
|
|
11
|
+
"or": {
|
|
12
|
+
"product": [
|
|
13
|
+
{"@type": "Product", "value": "", "term.termType": "waste"}
|
|
14
|
+
],
|
|
15
|
+
"completeness.waste": ""
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
RETURNS = {
|
|
20
|
+
"Emission": [{
|
|
21
|
+
"value": "",
|
|
22
|
+
"methodTier": "tier 1"
|
|
23
|
+
}]
|
|
24
|
+
}
|
|
25
|
+
LOOKUPS = {
|
|
26
|
+
"waste": "n2oEfSchmidt2007"
|
|
27
|
+
}
|
|
28
|
+
TERM_ID = 'n2OToAirWasteTreatmentDirect'
|
|
29
|
+
TIER = EmissionMethodTier.TIER_1.value
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _emission(value: float):
|
|
33
|
+
emission = _new_emission(TERM_ID, MODEL)
|
|
34
|
+
emission['value'] = [value]
|
|
35
|
+
emission['methodTier'] = TIER
|
|
36
|
+
return emission
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _run(waste_values: list):
|
|
40
|
+
value = list_sum(waste_values)
|
|
41
|
+
return [_emission(value)]
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _should_run(cycle: dict):
|
|
45
|
+
waste_values = get_waste_values(TERM_ID, cycle, LOOKUPS['waste'])
|
|
46
|
+
has_waste = len(waste_values) > 0
|
|
47
|
+
|
|
48
|
+
logRequirements(cycle, model=MODEL, term=TERM_ID,
|
|
49
|
+
has_waste=has_waste)
|
|
50
|
+
|
|
51
|
+
should_run = any([has_waste])
|
|
52
|
+
logShouldRun(cycle, MODEL, TERM_ID, should_run, methodTier=TIER)
|
|
53
|
+
return should_run, waste_values
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def run(cycle: dict):
|
|
57
|
+
should_run, waste_values = _should_run(cycle)
|
|
58
|
+
return _run(waste_values) if should_run else []
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
from hestia_earth.schema import EmissionMethodTier
|
|
2
|
+
from hestia_earth.utils.tools import list_sum
|
|
3
|
+
|
|
4
|
+
from hestia_earth.models.log import logRequirements, logShouldRun
|
|
5
|
+
from hestia_earth.models.utils.emission import _new_emission
|
|
6
|
+
from .utils import get_waste_values
|
|
7
|
+
from . import MODEL
|
|
8
|
+
|
|
9
|
+
REQUIREMENTS = {
|
|
10
|
+
"Cycle": {
|
|
11
|
+
"or": {
|
|
12
|
+
"product": [
|
|
13
|
+
{"@type": "Product", "value": "", "term.termType": "waste"}
|
|
14
|
+
],
|
|
15
|
+
"completeness.waste": ""
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
RETURNS = {
|
|
20
|
+
"Emission": [{
|
|
21
|
+
"value": "",
|
|
22
|
+
"methodTier": "tier 1"
|
|
23
|
+
}]
|
|
24
|
+
}
|
|
25
|
+
LOOKUPS = {
|
|
26
|
+
"waste": "nh3EfSchmidt2007"
|
|
27
|
+
}
|
|
28
|
+
TERM_ID = 'nh3ToAirWasteTreatment'
|
|
29
|
+
TIER = EmissionMethodTier.TIER_1.value
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _emission(value: float):
|
|
33
|
+
emission = _new_emission(TERM_ID, MODEL)
|
|
34
|
+
emission['value'] = [value]
|
|
35
|
+
emission['methodTier'] = TIER
|
|
36
|
+
return emission
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _run(waste_values: list):
|
|
40
|
+
value = list_sum(waste_values)
|
|
41
|
+
return [_emission(value)]
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def _should_run(cycle: dict):
|
|
45
|
+
waste_values = get_waste_values(TERM_ID, cycle, LOOKUPS['waste'])
|
|
46
|
+
has_waste = len(waste_values) > 0
|
|
47
|
+
|
|
48
|
+
logRequirements(cycle, model=MODEL, term=TERM_ID,
|
|
49
|
+
has_waste=has_waste)
|
|
50
|
+
|
|
51
|
+
should_run = any([has_waste])
|
|
52
|
+
logShouldRun(cycle, MODEL, TERM_ID, should_run, methodTier=TIER)
|
|
53
|
+
return should_run, waste_values
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def run(cycle: dict):
|
|
57
|
+
should_run, waste_values = _should_run(cycle)
|
|
58
|
+
return _run(waste_values) if should_run else []
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
"""
|
|
2
2
|
Management node with data gap-filled data from cycles.
|
|
3
3
|
"""
|
|
4
|
-
from typing import List
|
|
4
|
+
from typing import List, Any
|
|
5
5
|
from functools import reduce
|
|
6
6
|
from hestia_earth.schema import SchemaType, TermTermType
|
|
7
7
|
from hestia_earth.utils.api import download_hestia
|
|
8
8
|
from hestia_earth.utils.model import filter_list_term_type, linked_node
|
|
9
|
-
from hestia_earth.utils.tools import flatten
|
|
9
|
+
from hestia_earth.utils.tools import flatten, safe_parse_float
|
|
10
10
|
|
|
11
11
|
from hestia_earth.models.log import logRequirements, logShouldRun, log_blank_nodes_id
|
|
12
12
|
from hestia_earth.models.utils.term import get_lookup_value
|
|
@@ -37,6 +37,16 @@ REQUIREMENTS = {
|
|
|
37
37
|
],
|
|
38
38
|
"value": ""
|
|
39
39
|
}
|
|
40
|
+
],
|
|
41
|
+
"inputs": [
|
|
42
|
+
{
|
|
43
|
+
"@type": "Input",
|
|
44
|
+
"term.termType": [
|
|
45
|
+
"inorganicFertiliser",
|
|
46
|
+
"organicFertiliser",
|
|
47
|
+
"soilAmendment"
|
|
48
|
+
]
|
|
49
|
+
}
|
|
40
50
|
]
|
|
41
51
|
}]
|
|
42
52
|
}
|
|
@@ -53,9 +63,47 @@ RETURNS = {
|
|
|
53
63
|
"startDate": ""
|
|
54
64
|
}]
|
|
55
65
|
}
|
|
56
|
-
|
|
66
|
+
LOOKUPS = {
|
|
67
|
+
"crop": ["landCoverTermId"],
|
|
68
|
+
"forage": ["landCoverTermId"],
|
|
69
|
+
"inorganicFertiliser": "nitrogenContent",
|
|
70
|
+
"organicFertiliser": "ANIMAL_MANURE",
|
|
71
|
+
"soilAmendment": "PRACTICE_INCREASING_C_INPUT"
|
|
72
|
+
}
|
|
57
73
|
MODEL_KEY = 'management'
|
|
58
|
-
LAND_COVER_KEY = '
|
|
74
|
+
LAND_COVER_KEY = LOOKUPS['crop'][0]
|
|
75
|
+
ANIMAL_MANURE_USED_TERM_ID = "animalManureUsed"
|
|
76
|
+
INORGANIC_NITROGEN_FERTILISER_USED_TERM_ID = "inorganicNitrogenFertiliserUsed"
|
|
77
|
+
ORGANIC_FERTILISER_USED_TERM_ID = "organicFertiliserUsed"
|
|
78
|
+
AMENDMENT_INCREASING_C_USED_TERM_ID = "amendmentIncreasingSoilCarbonUsed"
|
|
79
|
+
INPUT_RULES = {
|
|
80
|
+
TermTermType.INORGANICFERTILISER.value: (
|
|
81
|
+
(
|
|
82
|
+
TermTermType.INORGANICFERTILISER.value, # Lookup column
|
|
83
|
+
lambda x: safe_parse_float(x) > 0, # Condition
|
|
84
|
+
INORGANIC_NITROGEN_FERTILISER_USED_TERM_ID # New term.
|
|
85
|
+
),
|
|
86
|
+
),
|
|
87
|
+
TermTermType.SOILAMENDMENT.value: (
|
|
88
|
+
(
|
|
89
|
+
TermTermType.SOILAMENDMENT.value,
|
|
90
|
+
lambda x: x is True,
|
|
91
|
+
AMENDMENT_INCREASING_C_USED_TERM_ID
|
|
92
|
+
),
|
|
93
|
+
),
|
|
94
|
+
TermTermType.ORGANICFERTILISER.value: (
|
|
95
|
+
(
|
|
96
|
+
TermTermType.SOILAMENDMENT.value,
|
|
97
|
+
lambda x: x is True,
|
|
98
|
+
ORGANIC_FERTILISER_USED_TERM_ID
|
|
99
|
+
),
|
|
100
|
+
(
|
|
101
|
+
TermTermType.ORGANICFERTILISER.value,
|
|
102
|
+
lambda x: x is True,
|
|
103
|
+
ANIMAL_MANURE_USED_TERM_ID
|
|
104
|
+
)
|
|
105
|
+
)
|
|
106
|
+
}
|
|
59
107
|
|
|
60
108
|
|
|
61
109
|
def management(data: dict):
|
|
@@ -74,7 +122,9 @@ def _include_start_end(cycle: dict, values: list):
|
|
|
74
122
|
return [(_include(cycle, ['startDate', 'endDate']) | v) for v in values]
|
|
75
123
|
|
|
76
124
|
|
|
77
|
-
def _copy_item_if_exists(source: dict, keys: List[str] =
|
|
125
|
+
def _copy_item_if_exists(source: dict, keys: List[str] = None, dest: dict = None) -> dict:
|
|
126
|
+
keys = keys or []
|
|
127
|
+
dest = dest or {}
|
|
78
128
|
return reduce(lambda p, c: p | ({c: source[c]} if c in source else {}), keys, dest)
|
|
79
129
|
|
|
80
130
|
|
|
@@ -96,6 +146,50 @@ def _get_items_with_relevant_term_type(cycles: List[dict], item_name: str, relev
|
|
|
96
146
|
)
|
|
97
147
|
|
|
98
148
|
|
|
149
|
+
def _get_lookup_with_debug(term: dict, column: str) -> Any:
|
|
150
|
+
get_lookup_value(term, column, model_key=MODEL_KEY, land_cover_key=LAND_COVER_KEY)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
def _data_from_input(cycle: dict, term_id: str) -> dict:
|
|
154
|
+
return {
|
|
155
|
+
"term": {
|
|
156
|
+
"@type": "Term",
|
|
157
|
+
"@id": term_id,
|
|
158
|
+
"termType": "landUseManagement"
|
|
159
|
+
},
|
|
160
|
+
"value": True,
|
|
161
|
+
"startDate": cycle["startDate"],
|
|
162
|
+
"endDate": cycle["endDate"]
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
def _process_rule(cycle, term, term_type) -> List:
|
|
167
|
+
relevant_terms = []
|
|
168
|
+
for column, condition, new_term in INPUT_RULES[term_type]:
|
|
169
|
+
lookup_result = _get_lookup_with_debug(term, LOOKUPS[column])
|
|
170
|
+
|
|
171
|
+
if condition(lookup_result):
|
|
172
|
+
relevant_terms.append(_data_from_input(cycle=cycle, term_id=new_term))
|
|
173
|
+
|
|
174
|
+
return relevant_terms
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def _get_relevant_inputs(cycles: List[dict]) -> List:
|
|
178
|
+
relevant_inputs = []
|
|
179
|
+
for cycle in [c for c in cycles if "inputs" in c]:
|
|
180
|
+
for i in cycle["inputs"]:
|
|
181
|
+
if i.get("term", {}).get("termType", "") in INPUT_RULES:
|
|
182
|
+
relevant_inputs.extend(
|
|
183
|
+
_process_rule(
|
|
184
|
+
cycle=cycle,
|
|
185
|
+
term=i.get("term", {}),
|
|
186
|
+
term_type=i.get("term", {}).get("termType", "")
|
|
187
|
+
)
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
return relevant_inputs
|
|
191
|
+
|
|
192
|
+
|
|
99
193
|
def _should_run(site: dict):
|
|
100
194
|
# Only get related cycles once.
|
|
101
195
|
cycles = related_cycles(site.get("@id"))
|
|
@@ -148,6 +242,7 @@ def _should_run(site: dict):
|
|
|
148
242
|
)
|
|
149
243
|
]
|
|
150
244
|
|
|
245
|
+
relevant_inputs = _get_relevant_inputs(cycles)
|
|
151
246
|
logRequirements(
|
|
152
247
|
site,
|
|
153
248
|
model=MODEL,
|
|
@@ -155,14 +250,14 @@ def _should_run(site: dict):
|
|
|
155
250
|
model_key=MODEL_KEY,
|
|
156
251
|
products_crop_forage_ids=log_blank_nodes_id(products_crop_forage),
|
|
157
252
|
products_land_cover_ids=log_blank_nodes_id(products_land_cover),
|
|
158
|
-
practice_ids=log_blank_nodes_id(practices)
|
|
253
|
+
practice_ids=log_blank_nodes_id(practices),
|
|
254
|
+
inputs=log_blank_nodes_id(relevant_inputs)
|
|
159
255
|
)
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
return should_run, products_crop_forage + products_land_cover, practices
|
|
256
|
+
should_run = any(products_crop_forage + products_land_cover + practices + relevant_inputs)
|
|
257
|
+
logShouldRun(site, MODEL, None, should_run=should_run, model_key=MODEL_KEY)
|
|
258
|
+
return should_run, products_crop_forage + products_land_cover, practices, relevant_inputs
|
|
164
259
|
|
|
165
260
|
|
|
166
261
|
def run(site: dict):
|
|
167
|
-
should_run, products, practices = _should_run(site)
|
|
168
|
-
return list(map(management, products + practices)) if should_run else []
|
|
262
|
+
should_run, products, practices, inputs = _should_run(site)
|
|
263
|
+
return list(map(management, products + practices + inputs)) if should_run else []
|
|
@@ -16,7 +16,7 @@ from . import MODEL
|
|
|
16
16
|
REQUIREMENTS = {
|
|
17
17
|
"Site": {
|
|
18
18
|
"measurements": [
|
|
19
|
-
{"@type": "Measurement", "depthUpper": "", "depthLower": ""}
|
|
19
|
+
{"@type": "Measurement", "depthUpper": "", "depthLower": "", "value": ""}
|
|
20
20
|
]
|
|
21
21
|
}
|
|
22
22
|
}
|
|
@@ -159,21 +159,21 @@ def _get_needed_depths(site: dict) -> list:
|
|
|
159
159
|
|
|
160
160
|
def _should_run(site: dict, model_key: str):
|
|
161
161
|
# we only work with measurements with depths
|
|
162
|
-
measurements = [
|
|
163
|
-
m
|
|
164
|
-
|
|
165
|
-
]
|
|
162
|
+
measurements = [m for m in site.get("measurements", []) if all([
|
|
163
|
+
get_lookup_value(m.get("term", {}), LOOKUPS["measurement"][0], model=MODEL, model_key=model_key),
|
|
164
|
+
m.get('value', [])
|
|
165
|
+
])]
|
|
166
166
|
|
|
167
167
|
measurements_with_depths = [m for m in measurements if all([
|
|
168
|
-
"depthUpper" in m
|
|
169
|
-
"depthLower" in m
|
|
168
|
+
"depthUpper" in m,
|
|
169
|
+
"depthLower" in m,
|
|
170
170
|
(int(m.get("depthUpper", 0)), int(m.get("depthLower", 0))) not in STANDARD_DEPTHS
|
|
171
171
|
])]
|
|
172
172
|
has_measurements_with_depths = len(measurements_with_depths) > 0
|
|
173
173
|
|
|
174
174
|
measurements_missing_depth_recommended = [m for m in measurements if all([
|
|
175
|
-
"depthUpper" not in m
|
|
176
|
-
"depthLower" not in m
|
|
175
|
+
"depthUpper" not in m,
|
|
176
|
+
"depthLower" not in m,
|
|
177
177
|
not get_lookup_value(m.get("term", {}), LOOKUPS["measurement"][1], model=MODEL, model_key=model_key)
|
|
178
178
|
])]
|
|
179
179
|
|
|
@@ -134,4 +134,7 @@ def first_day_of_month(year: int, month: int):
|
|
|
134
134
|
|
|
135
135
|
|
|
136
136
|
def last_day_of_month(year: int, month: int):
|
|
137
|
-
|
|
137
|
+
# handle special case month 12
|
|
138
|
+
return datetime.date(int(year), 12, 31) if month == 12 else (
|
|
139
|
+
datetime.date(int(year) + int(int(month) / 12), (int(month) % 12) + 1, 1) - datetime.timedelta(days=1)
|
|
140
|
+
)
|
|
@@ -7,10 +7,12 @@ FAO_EQUIVALENT_LOOKUP_COLUMN = 'animalProductGroupingFAOEquivalent'
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
def get_animalProduct_lookup_value(model: str, term_id: str, column: str):
|
|
10
|
-
return get_lookup_value(
|
|
11
|
-
|
|
10
|
+
return get_lookup_value(
|
|
11
|
+
{'@id': term_id, 'termType': TermTermType.ANIMALPRODUCT.value}, column, model=model, term=term_id
|
|
12
|
+
) if term_id else None
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
def get_animalProduct_grouping_fao(model: str, term: dict):
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
term_id = term.get('@id')
|
|
17
|
+
fao_product_id = get_animalProduct_lookup_value(model, term_id, FAO_EQUIVALENT_LOOKUP_COLUMN)
|
|
18
|
+
return get_animalProduct_lookup_value(model, fao_product_id or term_id, FAO_LOOKUP_COLUMN)
|
|
@@ -37,9 +37,9 @@ from .term import get_lookup_value
|
|
|
37
37
|
|
|
38
38
|
|
|
39
39
|
def group_by_keys(group_keys: list = ['term']):
|
|
40
|
-
def run(group: dict,
|
|
41
|
-
group_key = '-'.join(non_empty_list(map(lambda v:
|
|
42
|
-
group[group_key] = group.get(group_key, []) + [
|
|
40
|
+
def run(group: dict, node: dict):
|
|
41
|
+
group_key = '-'.join(non_empty_list(map(lambda v: node.get(v, {}).get('@id'), group_keys)))
|
|
42
|
+
group[group_key] = group.get(group_key, []) + [node]
|
|
43
43
|
return group
|
|
44
44
|
return run
|
|
45
45
|
|
|
@@ -1161,9 +1161,10 @@ def group_nodes_by_year_and_month(
|
|
|
1161
1161
|
for year in range(range_start, range_end):
|
|
1162
1162
|
for month in range(1, 13):
|
|
1163
1163
|
|
|
1164
|
+
datestr_incomplete = f"{year}-{month:02}"
|
|
1164
1165
|
group_datetime_range = DatetimeRange(
|
|
1165
|
-
start=safe_parse_date(_gapfill_datestr(
|
|
1166
|
-
end=safe_parse_date(_gapfill_datestr(
|
|
1166
|
+
start=safe_parse_date(_gapfill_datestr(datestr_incomplete, DatestrGapfillMode.START)),
|
|
1167
|
+
end=safe_parse_date(_gapfill_datestr(datestr_incomplete, DatestrGapfillMode.END))
|
|
1167
1168
|
)
|
|
1168
1169
|
|
|
1169
1170
|
is_final_month = _datetime_within_range(node_datetime_range.end, group_datetime_range)
|
|
@@ -188,6 +188,12 @@ PRODUCT_UNITS_CONVERSIONS = {
|
|
|
188
188
|
]
|
|
189
189
|
},
|
|
190
190
|
Units.KG_LIVEWEIGHT.value: {
|
|
191
|
+
Units.NUMBER.value: [
|
|
192
|
+
('liveweightPerHead', True)
|
|
193
|
+
],
|
|
194
|
+
Units.HEAD.value: [
|
|
195
|
+
('liveweightPerHead', True)
|
|
196
|
+
],
|
|
191
197
|
Units.KG_LIVEWEIGHT.value: [],
|
|
192
198
|
Units.KG_COLD_CARCASS_WEIGHT.value: [
|
|
193
199
|
('processingConversionLiveweightToColdCarcassWeight', True)
|
|
@@ -224,7 +230,9 @@ PRODUCT_UNITS_CONVERSIONS = {
|
|
|
224
230
|
},
|
|
225
231
|
Units.KG_COLD_DRESSED_CARCASS_WEIGHT.value: {
|
|
226
232
|
Units.KG_LIVEWEIGHT.value: [
|
|
227
|
-
('processingConversionLiveweightToColdDressedCarcassWeight', False)
|
|
233
|
+
('processingConversionLiveweightToColdDressedCarcassWeight', False),
|
|
234
|
+
# fallback when cold dressed carcass weight is not provided
|
|
235
|
+
('processingConversionLiveweightToColdCarcassWeight', False)
|
|
228
236
|
],
|
|
229
237
|
Units.KG_COLD_DRESSED_CARCASS_WEIGHT.value: [],
|
|
230
238
|
Units.KG_COLD_CARCASS_WEIGHT.value: [],
|
|
@@ -603,26 +603,3 @@ def get_pasture_system_terms():
|
|
|
603
603
|
'name': 'pasture'
|
|
604
604
|
}, limit=LIMIT)
|
|
605
605
|
return list(map(lambda n: n["@id"], terms))
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
def get_long_fallow_land_cover_terms():
|
|
609
|
-
"""
|
|
610
|
-
Find all `landCover` terms with the name `long fallow`:
|
|
611
|
-
https://hestia.earth/glossary?termType=landCover&query=long%fallow
|
|
612
|
-
|
|
613
|
-
Returns
|
|
614
|
-
-------
|
|
615
|
-
list
|
|
616
|
-
List of matching term `@id` as `str`.
|
|
617
|
-
"""
|
|
618
|
-
terms = search({
|
|
619
|
-
"bool": {
|
|
620
|
-
"must": [
|
|
621
|
-
{"match": {"@type": SchemaType.TERM.value}},
|
|
622
|
-
{"match": {"termType.keyword": TermTermType.LANDCOVER.value}},
|
|
623
|
-
{"match_phrase_prefix": {"name": "long"}},
|
|
624
|
-
{"match": {"name": "fallow"}}
|
|
625
|
-
],
|
|
626
|
-
}
|
|
627
|
-
}, limit=LIMIT)
|
|
628
|
-
return list(map(lambda n: n["@id"], terms))
|
hestia_earth/models/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
VERSION = '0.59.
|
|
1
|
+
VERSION = '0.59.6'
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: hestia-earth-models
|
|
3
|
-
Version: 0.59.
|
|
3
|
+
Version: 0.59.6
|
|
4
4
|
Summary: Hestia's set of modules for filling gaps in the activity data using external datasets (e.g. populating soil properties with a geospatial dataset using provided coordinates) and internal lookups (e.g. populating machinery use from fuel use). Includes rules for when gaps should be filled versus not (e.g. never gap fill yield, gap fill crop residue if yield provided etc.).
|
|
5
5
|
Home-page: https://gitlab.com/hestia-earth/hestia-engine-models
|
|
6
6
|
Author: Hestia Team
|