hestia-earth-models 0.65.8__py3-none-any.whl → 0.65.10__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.
- hestia_earth/models/cml2001Baseline/abioticResourceDepletionFossilFuels.py +3 -5
- hestia_earth/models/cml2001Baseline/abioticResourceDepletionMineralsAndMetals.py +1 -1
- hestia_earth/models/config/Cycle.json +368 -388
- hestia_earth/models/config/Site.json +18 -0
- hestia_earth/models/config/__init__.py +6 -0
- hestia_earth/models/config/run-calculations.json +5 -5
- hestia_earth/models/config/trigger-calculations.json +1 -1
- hestia_earth/models/cycle/materialAndSubstrate.py +1 -1
- hestia_earth/models/cycle/milkYield.py +9 -6
- hestia_earth/models/cycle/product/economicValueShare.py +8 -4
- hestia_earth/models/cycle/product/revenue.py +11 -7
- hestia_earth/models/environmentalFootprintV3/soilQualityIndexLandTransformation.py +12 -4
- hestia_earth/models/faostat2018/product/price.py +1 -1
- hestia_earth/models/geospatialDatabase/utils.py +22 -17
- hestia_earth/models/hestia/landCover.py +2 -2
- hestia_earth/models/mocking/search-results.json +843 -843
- hestia_earth/models/site/defaultMethodClassification.py +35 -0
- hestia_earth/models/site/defaultMethodClassificationDescription.py +39 -0
- hestia_earth/models/site/management.py +34 -23
- hestia_earth/models/utils/impact_assessment.py +5 -3
- hestia_earth/models/utils/lookup.py +3 -3
- hestia_earth/models/version.py +1 -1
- {hestia_earth_models-0.65.8.dist-info → hestia_earth_models-0.65.10.dist-info}/METADATA +2 -2
- {hestia_earth_models-0.65.8.dist-info → hestia_earth_models-0.65.10.dist-info}/RECORD +39 -35
- tests/models/cml2001Baseline/test_abioticResourceDepletionFossilFuels.py +2 -16
- tests/models/cml2001Baseline/test_abioticResourceDepletionMineralsAndMetals.py +2 -16
- tests/models/edip2003/test_ozoneDepletionPotential.py +0 -13
- tests/models/environmentalFootprintV3/test_soilQualityIndexLandTransformation.py +8 -15
- tests/models/hestia/test_landCover.py +2 -1
- tests/models/ipcc2021/test_gwp100.py +0 -9
- tests/models/poschEtAl2008/test_terrestrialAcidificationPotentialAccumulatedExceedance.py +0 -14
- tests/models/poschEtAl2008/test_terrestrialEutrophicationPotentialAccumulatedExceedance.py +0 -14
- tests/models/site/test_defaultMethodClassification.py +18 -0
- tests/models/site/test_defaultMethodClassificationDescription.py +18 -0
- tests/models/site/test_management.py +2 -1
- tests/models/test_config.py +11 -2
- {hestia_earth_models-0.65.8.dist-info → hestia_earth_models-0.65.10.dist-info}/LICENSE +0 -0
- {hestia_earth_models-0.65.8.dist-info → hestia_earth_models-0.65.10.dist-info}/WHEEL +0 -0
- {hestia_earth_models-0.65.8.dist-info → hestia_earth_models-0.65.10.dist-info}/top_level.txt +0 -0
@@ -432,6 +432,24 @@
|
|
432
432
|
"stage": 2
|
433
433
|
}
|
434
434
|
],
|
435
|
+
[
|
436
|
+
{
|
437
|
+
"key": "defaultMethodClassification",
|
438
|
+
"model": "site",
|
439
|
+
"value": "defaultMethodClassification",
|
440
|
+
"runStrategy": "add_key_if_missing",
|
441
|
+
"mergeStrategy": "default",
|
442
|
+
"stage": 2
|
443
|
+
},
|
444
|
+
{
|
445
|
+
"key": "defaultMethodClassificationDescription",
|
446
|
+
"model": "site",
|
447
|
+
"value": "defaultMethodClassificationDescription",
|
448
|
+
"runStrategy": "add_key_if_missing",
|
449
|
+
"mergeStrategy": "default",
|
450
|
+
"stage": 2
|
451
|
+
}
|
452
|
+
],
|
435
453
|
[
|
436
454
|
{
|
437
455
|
"key": "measurements",
|
@@ -69,3 +69,9 @@ def load_run_config(node_type: str, stage: int):
|
|
69
69
|
|
70
70
|
def load_trigger_config(node_type: str, stage: int):
|
71
71
|
return _load_stage_config('trigger-calculations', node_type, stage)
|
72
|
+
|
73
|
+
|
74
|
+
def get_max_stage(node_type: str):
|
75
|
+
config = _load_config('run-calculations').get(node_type, {})
|
76
|
+
stages = list(map(lambda k: int(k.replace('stage-', '')), config.keys()))
|
77
|
+
return max(stages)
|
@@ -15,11 +15,6 @@
|
|
15
15
|
"key": "nested",
|
16
16
|
"type": "Site",
|
17
17
|
"stage": 1
|
18
|
-
},
|
19
|
-
{
|
20
|
-
"key": "nested",
|
21
|
-
"type": "ImpactAssessment",
|
22
|
-
"stage": 1
|
23
18
|
}
|
24
19
|
],
|
25
20
|
"stage-2": [
|
@@ -27,6 +22,11 @@
|
|
27
22
|
"key": "nested",
|
28
23
|
"type": "Site",
|
29
24
|
"stage": 2
|
25
|
+
},
|
26
|
+
{
|
27
|
+
"key": "nested",
|
28
|
+
"type": "ImpactAssessment",
|
29
|
+
"stage": 1
|
30
30
|
}
|
31
31
|
]
|
32
32
|
},
|
@@ -106,7 +106,7 @@ def _has_depreciated_term(term: dict):
|
|
106
106
|
def _should_run_input(cycle: dict, input_node: dict) -> bool:
|
107
107
|
term = input_node.get('term', {})
|
108
108
|
term_id = term.get('@id')
|
109
|
-
has_lifespan = input_node.get('lifespan'
|
109
|
+
has_lifespan = input_node.get('lifespan') or 0 > 0
|
110
110
|
has_valid_value = _get_value(input_node, 'value') > 0
|
111
111
|
has_depreciated_term = _has_depreciated_term(term)
|
112
112
|
|
@@ -39,12 +39,15 @@ REQUIREMENTS = {
|
|
39
39
|
}
|
40
40
|
}
|
41
41
|
RETURNS = {
|
42
|
-
"
|
43
|
-
"
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
42
|
+
"Animal": [{
|
43
|
+
"practices": [{
|
44
|
+
"@type": "Practice",
|
45
|
+
"value": "",
|
46
|
+
"min": "",
|
47
|
+
"max": "",
|
48
|
+
"sd": "",
|
49
|
+
"statsDefinition": "modelled"
|
50
|
+
}]
|
48
51
|
}]
|
49
52
|
}
|
50
53
|
LOOKUPS = {
|
@@ -15,7 +15,7 @@ corresponding value, the `economicValueShare` will be proportionally distributed
|
|
15
15
|
from hestia_earth.utils.model import find_term_match
|
16
16
|
from hestia_earth.utils.tools import list_sum
|
17
17
|
|
18
|
-
from hestia_earth.models.log import logRequirements, logShouldRun
|
18
|
+
from hestia_earth.models.log import logRequirements, logShouldRun, log_as_table
|
19
19
|
from hestia_earth.models.utils.blank_node import get_lookup_value
|
20
20
|
from hestia_earth.models.utils.cycle import unique_currencies
|
21
21
|
from .utils import lookup_share
|
@@ -55,7 +55,7 @@ MIN_COMPLETE_VALUE = 80 # when the products are complete lower the min threshol
|
|
55
55
|
|
56
56
|
|
57
57
|
def _product(product: dict, value: float):
|
58
|
-
return
|
58
|
+
return product | {MODEL_KEY: value}
|
59
59
|
|
60
60
|
|
61
61
|
def _is_complete(cycle: dict): return cycle.get('completeness', {}).get('product', False)
|
@@ -69,7 +69,7 @@ def _total_evs(products: list): return sum([p.get(MODEL_KEY, 0) for p in product
|
|
69
69
|
|
70
70
|
def _product_with_value(product: dict):
|
71
71
|
value = product.get(MODEL_KEY, lookup_share(MODEL_KEY, product))
|
72
|
-
return
|
72
|
+
return product | {MODEL_KEY: value} if value is not None else product
|
73
73
|
|
74
74
|
|
75
75
|
def _rescale_value(products: list, total: float):
|
@@ -87,7 +87,11 @@ def _should_run_by_default(cycle: dict, products: list):
|
|
87
87
|
for p in products:
|
88
88
|
term_id = p.get('term', {}).get('@id')
|
89
89
|
logRequirements(cycle, model=MODEL, term=term_id, key=MODEL_KEY, by=run_by,
|
90
|
-
all_with_economicValueShare=all_with_economicValueShare
|
90
|
+
all_with_economicValueShare=all_with_economicValueShare,
|
91
|
+
products_with_share=log_as_table([{
|
92
|
+
'id': p.get('term', {}).get('@id'),
|
93
|
+
MODEL_KEY: p.get(MODEL_KEY)
|
94
|
+
} for p in products]))
|
91
95
|
logShouldRun(cycle, MODEL, term_id, should_run, key=MODEL_KEY, by=run_by)
|
92
96
|
|
93
97
|
return should_run
|
@@ -48,18 +48,22 @@ def _run(cycle: dict):
|
|
48
48
|
def _should_run(cycle: dict):
|
49
49
|
def should_run_product(product: dict):
|
50
50
|
term_id = product.get('term', {}).get('@id')
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
is_yield_0 =
|
55
|
-
|
51
|
+
|
52
|
+
value = list_sum(product.get('value') or [], default=None)
|
53
|
+
has_yield = bool(value)
|
54
|
+
is_yield_0 = value == 0
|
55
|
+
|
56
|
+
price = product.get('price') or -1
|
57
|
+
has_price = price > 0
|
58
|
+
is_price_0 = price == 0
|
56
59
|
|
57
60
|
logRequirements(cycle, model=MODEL, term=term_id, key=MODEL_KEY,
|
58
|
-
|
61
|
+
has_yield=has_yield,
|
62
|
+
has_price=has_price,
|
59
63
|
is_yield_0=is_yield_0,
|
60
64
|
is_price_0=is_price_0)
|
61
65
|
|
62
|
-
should_run = any([
|
66
|
+
should_run = any([has_yield and has_price, is_yield_0, is_price_0])
|
63
67
|
logShouldRun(cycle, MODEL, term_id, should_run, key=MODEL_KEY)
|
64
68
|
return should_run
|
65
69
|
return should_run_product
|
@@ -25,7 +25,8 @@ REQUIREMENTS = {
|
|
25
25
|
{
|
26
26
|
"@type": "Indicator",
|
27
27
|
"term.termType": "resourceUse",
|
28
|
-
"term
|
28
|
+
"term.@id": ["landTransformation20YearAverageInputsProduction",
|
29
|
+
"landTransformation20YearAverageDuringCycle"],
|
29
30
|
"value": "> 0",
|
30
31
|
"landCover": {"@type": "Term", "term.termType": "landCover"},
|
31
32
|
"previousLandCover": {"@type": "Term", "term.termType": "landCover"}
|
@@ -74,6 +75,10 @@ def _run(transformations: List[dict]):
|
|
74
75
|
return _indicator(list_sum(values))
|
75
76
|
|
76
77
|
|
78
|
+
def _is_valid_indicator(indicator: dict) -> bool:
|
79
|
+
return indicator['term']['@id'] in REQUIREMENTS['ImpactAssessment']['emissionsResourceUse'][0]['term.@id']
|
80
|
+
|
81
|
+
|
77
82
|
def _should_run(impact_assessment: dict) -> Tuple[bool, list]:
|
78
83
|
resource_uses = filter_list_term_type(impact_assessment.get('emissionsResourceUse', []), TermTermType.RESOURCEUSE)
|
79
84
|
found_transformations = [
|
@@ -82,7 +87,9 @@ def _should_run(impact_assessment: dict) -> Tuple[bool, list]:
|
|
82
87
|
'land-cover-id-from': transformation_indicator.get('previousLandCover', {}).get("@id"),
|
83
88
|
'land-cover-id-to': transformation_indicator.get('landCover', {}).get("@id"),
|
84
89
|
'indicator-id': transformation_indicator.get('term', {}).get('@id', ''),
|
85
|
-
'
|
90
|
+
'indicator-is-valid': _is_valid_indicator(transformation_indicator),
|
91
|
+
'good-land-cover-term': all([bool(transformation_indicator.get('landCover')),
|
92
|
+
bool(transformation_indicator.get('previousLandCover'))]),
|
86
93
|
'country-id': get_country_id(impact_assessment),
|
87
94
|
'area-is-valid': _node_value(transformation_indicator) is not None and _node_value(
|
88
95
|
transformation_indicator) > 0,
|
@@ -112,19 +119,20 @@ def _should_run(impact_assessment: dict) -> Tuple[bool, list]:
|
|
112
119
|
valid_transformations_with_coef = [
|
113
120
|
t for t in found_transformations_with_coefficient if all([
|
114
121
|
t['area-is-valid'],
|
122
|
+
t['indicator-is-valid'],
|
115
123
|
t['factor-from'] is not None,
|
116
124
|
t['factor-to'] is not None
|
117
125
|
])
|
118
126
|
]
|
119
127
|
|
120
128
|
has_land_transformation_indicators = any([
|
121
|
-
indicator
|
129
|
+
_is_valid_indicator(indicator)
|
122
130
|
for indicator in resource_uses
|
123
131
|
])
|
124
132
|
|
125
133
|
all_transformations_are_valid = all(
|
126
134
|
[
|
127
|
-
all([t['area-is-valid'], t['good-land-cover-term']])
|
135
|
+
all([t['area-is-valid'], t['indicator-is-valid'], t['good-land-cover-term']])
|
128
136
|
for t in found_transformations_with_coefficient
|
129
137
|
]
|
130
138
|
) if found_transformations_with_coefficient else False
|
@@ -129,7 +129,7 @@ def _run_by_country(cycle: dict, product: dict, country_id: str, year: int = Non
|
|
129
129
|
term_type = product_term.get('termType')
|
130
130
|
term_units = product_term.get('units')
|
131
131
|
|
132
|
-
has_yield = len(product.get('value'
|
132
|
+
has_yield = len(product.get('value') or []) > 0
|
133
133
|
not_already_set = MODEL_KEY not in product.keys()
|
134
134
|
|
135
135
|
# get the grouping used in region lookup
|
@@ -29,6 +29,11 @@ def to_celcius(kelvin_value: int): return kelvin_value - KELVIN_0 if kelvin_valu
|
|
29
29
|
def use_geopandas(): return os.getenv('HEE_USE_GEOPANDAS', 'false') == 'true'
|
30
30
|
|
31
31
|
|
32
|
+
def _has_cache(site: dict):
|
33
|
+
cache = cached_value(site, key=CACHE_VALUE, default=None)
|
34
|
+
return bool(cache)
|
35
|
+
|
36
|
+
|
32
37
|
def _cached_value(site: dict, key: str):
|
33
38
|
return cached_value(site, key=CACHE_VALUE, default={}).get(key)
|
34
39
|
|
@@ -166,23 +171,23 @@ def download(term: str, site: dict, data: dict, only_coordinates=False) -> dict:
|
|
166
171
|
Data returned from the API.
|
167
172
|
"""
|
168
173
|
# check if we have cached the result already, else run and parse result
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
174
|
+
if _has_cache(site):
|
175
|
+
# even if the cached value is null, we do not want to run the query again
|
176
|
+
# TODO: we might want to store the date it was cached, and run again if more than 30 days
|
177
|
+
return _get_cached_data(term, site, data)
|
178
|
+
|
179
|
+
location_data = geospatial_data(site, only_coordinates=only_coordinates)
|
180
|
+
query = {
|
181
|
+
'ee_type': data.get('ee_type'),
|
182
|
+
**location_data,
|
183
|
+
'collections': [
|
184
|
+
{
|
185
|
+
**data,
|
186
|
+
'collection': _collection_name(data.get('collection'))
|
187
|
+
}
|
188
|
+
]
|
189
|
+
}
|
190
|
+
value = _parse_run_query(term, query)
|
186
191
|
if value is None:
|
187
192
|
debugValues(site, model=MODEL, term=term, value_from_earth_engine=None)
|
188
193
|
return value
|
@@ -34,7 +34,7 @@ from .utils import (
|
|
34
34
|
crop_ipcc_land_use_category,
|
35
35
|
)
|
36
36
|
from . import MODEL
|
37
|
-
from ..utils.blank_node import _node_date, DatestrFormat
|
37
|
+
from ..utils.blank_node import _node_date, DatestrFormat, _gapfill_datestr, DatestrGapfillMode
|
38
38
|
from ..utils.constant import DAYS_IN_YEAR
|
39
39
|
|
40
40
|
REQUIREMENTS = {
|
@@ -697,7 +697,7 @@ def _collect_land_use_types(nodes: list) -> list:
|
|
697
697
|
{
|
698
698
|
"id": node.get("term", {}).get("@id"),
|
699
699
|
"land-use-type": _get_land_use_term_from_node(node),
|
700
|
-
"endDate": node.get("endDate")
|
700
|
+
"endDate": _gapfill_datestr(datestr=node.get("endDate"), mode=DatestrGapfillMode.END)[:10]
|
701
701
|
} for node in nodes
|
702
702
|
]
|
703
703
|
|