hestia-earth-models 0.72.0__py3-none-any.whl → 0.72.2__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/resourceUseEnergyDepletionInputsProduction.py +2 -1
- hestia_earth/models/cml2001Baseline/resourceUseMineralsAndMetalsInputsProduction.py +2 -1
- hestia_earth/models/config/ImpactAssessment.json +1964 -1918
- hestia_earth/models/ecoalimV9/cycle.py +1 -0
- hestia_earth/models/ecoalimV9/impact_assessment.py +1 -0
- hestia_earth/models/ecoinventV3/__init__.py +1 -0
- hestia_earth/models/ecoinventV3AndEmberClimate/__init__.py +1 -0
- hestia_earth/models/environmentalFootprintV3_1/environmentalFootprintSingleOverallScore.py +19 -3
- hestia_earth/models/hestia/landCover.py +10 -2
- hestia_earth/models/ipcc2019/co2ToAirUreaHydrolysis.py +27 -27
- hestia_earth/models/linkedImpactAssessment/emissions.py +1 -0
- hestia_earth/models/linkedImpactAssessment/utils.py +16 -16
- hestia_earth/models/mocking/search-results.json +660 -660
- hestia_earth/models/version.py +1 -1
- {hestia_earth_models-0.72.0.dist-info → hestia_earth_models-0.72.2.dist-info}/METADATA +1 -1
- {hestia_earth_models-0.72.0.dist-info → hestia_earth_models-0.72.2.dist-info}/RECORD +21 -21
- tests/models/environmentalFootprintV3_1/test_environmentalFootprintSingleOverallScore.py +22 -2
- tests/models/ipcc2019/test_co2ToAirUreaHydrolysis.py +10 -34
- {hestia_earth_models-0.72.0.dist-info → hestia_earth_models-0.72.2.dist-info}/LICENSE +0 -0
- {hestia_earth_models-0.72.0.dist-info → hestia_earth_models-0.72.2.dist-info}/WHEEL +0 -0
- {hestia_earth_models-0.72.0.dist-info → hestia_earth_models-0.72.2.dist-info}/top_level.txt +0 -0
@@ -81,6 +81,7 @@ def _add_emission(cycle: dict, input: dict):
|
|
81
81
|
emissions = ecoalim_values(ecoalim_key, 'emission')
|
82
82
|
for emission_term_id, value in emissions:
|
83
83
|
# log run on each emission so we know it did run
|
84
|
+
logShouldRun(cycle, MODEL, input_term_id, True, methodTier=TIER, emission_id=emission_term_id)
|
84
85
|
debugValues(cycle, model=MODEL, term=emission_term_id, model_key=MODEL_KEY,
|
85
86
|
value=value,
|
86
87
|
coefficient=coefficient,
|
@@ -81,6 +81,7 @@ def _add_indicator(cycle: dict, input: dict):
|
|
81
81
|
indicators = ecoalim_values(ecoalim_key, 'resourceUse')
|
82
82
|
for indicator_term_id, value in indicators:
|
83
83
|
# log run on each indicator so we know it did run
|
84
|
+
logShouldRun(cycle, MODEL, input_term_id, True, methodTier=TIER, emission_id=indicator_term_id)
|
84
85
|
debugValues(cycle, model=MODEL, term=indicator_term_id, model_key=MODEL_KEY,
|
85
86
|
value=value,
|
86
87
|
coefficient=coefficient,
|
@@ -89,6 +89,7 @@ def _add_emission(cycle: dict, input: dict):
|
|
89
89
|
emissions = ecoinventV3_emissions(ecoinventName)
|
90
90
|
for emission_term_id, value in emissions:
|
91
91
|
# log run on each emission so we know it did run
|
92
|
+
logShouldRun(cycle, MODEL, input_term_id, True, methodTier=TIER, emission_id=emission_term_id)
|
92
93
|
debugValues(cycle, model=MODEL, term=emission_term_id,
|
93
94
|
value=value,
|
94
95
|
coefficient=coefficient,
|
@@ -89,6 +89,7 @@ def _add_emission(cycle: dict, input: dict):
|
|
89
89
|
emissions = ecoinventV3_emissions(ecoinventName)
|
90
90
|
for emission_term_id, value in emissions:
|
91
91
|
# log run on each emission so we know it did run
|
92
|
+
logShouldRun(cycle, MODEL, input_term_id, True, methodTier=TIER, emission_id=emission_term_id)
|
92
93
|
debugValues(cycle, model=MODEL, term=emission_term_id,
|
93
94
|
value=value,
|
94
95
|
coefficient=coefficient,
|
@@ -1,8 +1,7 @@
|
|
1
|
-
from typing import List, Optional, Tuple
|
2
|
-
|
3
1
|
from hestia_earth.schema import TermTermType
|
4
2
|
from hestia_earth.utils.model import filter_list_term_type
|
5
3
|
from hestia_earth.utils.tools import list_sum
|
4
|
+
from typing import List, Optional, Tuple
|
6
5
|
|
7
6
|
from hestia_earth.models.log import logRequirements, logShouldRun, log_as_table, debugValues
|
8
7
|
from hestia_earth.models.utils.blank_node import get_lookup_value
|
@@ -89,6 +88,23 @@ def _indicator_factors(impact_assessment: dict, indicator: dict):
|
|
89
88
|
}
|
90
89
|
|
91
90
|
|
91
|
+
def _map_input_ids(value: dict) -> set[str]:
|
92
|
+
return set(map(lambda i: i.get('@id'), value.get('inputs', [])))
|
93
|
+
|
94
|
+
|
95
|
+
def _count_duplicate_indicators(reference_indicator: dict, indicators: list) -> int:
|
96
|
+
"""
|
97
|
+
Counts the number of `reference_indicator` indicators found in a list of indicators.
|
98
|
+
Uses indicator.term.@id and indicator.inputs to determine uniqueness.
|
99
|
+
"""
|
100
|
+
return sum([
|
101
|
+
1
|
102
|
+
for i in indicators
|
103
|
+
if (i["term"]["@id"] == reference_indicator["term"]["@id"]) and (
|
104
|
+
_map_input_ids(i) == _map_input_ids(reference_indicator))
|
105
|
+
])
|
106
|
+
|
107
|
+
|
92
108
|
def _indicator(value: float) -> dict:
|
93
109
|
indicator = _new_indicator(TERM_ID, MODEL)
|
94
110
|
indicator['value'] = value
|
@@ -115,7 +131,7 @@ def _should_run(impact_assessment: dict) -> Tuple[bool, list[dict]]:
|
|
115
131
|
processed_indicators = [{
|
116
132
|
"indicator": indicator['term']['@id'],
|
117
133
|
"valid-indicator": _valid_indicator(indicator),
|
118
|
-
"one-indicator-for-category":
|
134
|
+
"one-indicator-for-category": _count_duplicate_indicators(indicator, indicators) == 1,
|
119
135
|
"indicator-pef-category": indicator.get('term', {}).get('@id'),
|
120
136
|
} | _indicator_factors(impact_assessment, indicator) for indicator in indicators]
|
121
137
|
|
@@ -148,7 +148,7 @@ def cap_values(dictionary: dict, lower_limit: float = 0, upper_limit: float = 1)
|
|
148
148
|
|
149
149
|
def site_area_sum_to_100(dict_of_percentages: dict):
|
150
150
|
return False if dict_of_percentages == {} else (
|
151
|
-
math.isclose(sum(dict_of_percentages.values()), 1.0, rel_tol=0.
|
151
|
+
math.isclose(sum(dict_of_percentages.values()), 1.0, rel_tol=0.05) or
|
152
152
|
math.isclose(sum(dict_of_percentages.values()), 0.0, rel_tol=0.01)
|
153
153
|
)
|
154
154
|
|
@@ -581,6 +581,14 @@ def _get_year_from_landCover(node: dict):
|
|
581
581
|
return int(date[:4])
|
582
582
|
|
583
583
|
|
584
|
+
def _scale_site_area_errors(site_area: dict) -> dict:
|
585
|
+
"""Redistribute the result of any rounding error in proportion to the other land use types."""
|
586
|
+
# Positive errors would not have been capped, so won't be missing.
|
587
|
+
negative_errors = [v for v in site_area.values() if v < 0.0]
|
588
|
+
return {k: v + negative_errors[0] * v for k, v in site_area.items()} \
|
589
|
+
if negative_errors and abs(negative_errors[0]) < 1 and all([v < 1 for v in site_area.values()]) else site_area
|
590
|
+
|
591
|
+
|
584
592
|
def _should_run_historical_land_use_change(site: dict, nodes: list, land_use_type: str) -> tuple[bool, dict]:
|
585
593
|
# Assume a single management node for single-cropping.
|
586
594
|
return _should_run_historical_land_use_change_single_crop(
|
@@ -728,7 +736,7 @@ def _should_run_historical_land_use_change_single_crop(
|
|
728
736
|
if land_type != land_use_type
|
729
737
|
}
|
730
738
|
site_area[land_use_type] = 1 - sum(site_area.values())
|
731
|
-
capped_site_area = cap_values(dictionary=site_area
|
739
|
+
capped_site_area = cap_values(dictionary=_scale_site_area_errors(site_area))
|
732
740
|
|
733
741
|
sum_of_site_areas_is_100 = site_area_sum_to_100(capped_site_area)
|
734
742
|
site_type_allowed = site.get("siteType") in SITE_TYPES
|
@@ -2,7 +2,8 @@ from hestia_earth.schema import EmissionMethodTier
|
|
2
2
|
from hestia_earth.utils.tools import list_sum, safe_parse_float, non_empty_list
|
3
3
|
from hestia_earth.utils.model import find_term_match
|
4
4
|
|
5
|
-
from hestia_earth.models.log import
|
5
|
+
from hestia_earth.models.log import logRequirements, logShouldRun, log_as_table
|
6
|
+
from hestia_earth.models.utils import multiply_values
|
6
7
|
from hestia_earth.models.utils.completeness import _is_term_type_complete
|
7
8
|
from hestia_earth.models.utils.emission import _new_emission
|
8
9
|
from hestia_earth.models.utils.term import get_urea_terms
|
@@ -36,66 +37,65 @@ def _emission(value: float):
|
|
36
37
|
return emission
|
37
38
|
|
38
39
|
|
39
|
-
def
|
40
|
-
|
41
|
-
term_id = data.get('id')
|
42
|
-
values = data.get('values')
|
43
|
-
coeff = safe_parse_float(get_term_lookup(term_id, LOOKUPS['inorganicFertiliser'][2]), 1)
|
44
|
-
debugValues(cycle, model=MODEL, term=TERM_ID,
|
45
|
-
product=term_id,
|
46
|
-
coefficient=coeff)
|
47
|
-
return list_sum(values) * coeff
|
48
|
-
return exec
|
40
|
+
def _urea_emission_factor(term_id: str):
|
41
|
+
return safe_parse_float(get_term_lookup(term_id, LOOKUPS['inorganicFertiliser'][2]), None)
|
49
42
|
|
50
43
|
|
51
|
-
def _run(
|
52
|
-
value = list_sum(
|
44
|
+
def _run(urea_values: list):
|
45
|
+
value = list_sum([v.get('value') * v.get('factor') for v in urea_values if v.get('value')])
|
53
46
|
return [_emission(value)]
|
54
47
|
|
55
48
|
|
56
|
-
def
|
49
|
+
def _get_urea_value(cycle: dict, inputs: list, term_id: str):
|
57
50
|
inputs = list(filter(lambda i: i.get('term', {}).get('@id') == term_id, inputs))
|
58
51
|
values = [list_sum(i.get('value'), 0) for i in inputs if len(i.get('value', [])) > 0]
|
59
|
-
return
|
52
|
+
return list_sum(values, default=None)
|
60
53
|
|
61
54
|
|
62
55
|
def _should_run(cycle: dict):
|
56
|
+
is_fertiliser_complete = _is_term_type_complete(cycle, 'fertiliser')
|
63
57
|
inputs = cycle.get('inputs', [])
|
64
58
|
term_ids = get_urea_terms()
|
65
59
|
|
66
60
|
country_id = cycle.get('site', {}).get('country', {}).get('@id')
|
67
61
|
urea_share = get_country_breakdown(MODEL, TERM_ID, country_id, LOOKUPS['inorganicFertiliser'][0])
|
68
62
|
uan_share = get_country_breakdown(MODEL, TERM_ID, country_id, LOOKUPS['inorganicFertiliser'][1])
|
69
|
-
urea_unspecified_as_n = list_sum(find_term_match(inputs, UNSPECIFIED_TERM_ID).get('value', []))
|
63
|
+
urea_unspecified_as_n = list_sum(find_term_match(inputs, UNSPECIFIED_TERM_ID).get('value', []), default=None)
|
70
64
|
|
71
65
|
urea_values = [
|
72
66
|
{
|
73
|
-
'id':
|
74
|
-
'
|
75
|
-
|
67
|
+
'id': term_id,
|
68
|
+
'value': _get_urea_value(cycle, inputs, term_id),
|
69
|
+
'factor': _urea_emission_factor(term_id)
|
70
|
+
} for term_id in term_ids
|
76
71
|
] + non_empty_list([
|
77
72
|
{
|
78
73
|
'id': 'ureaKgN',
|
79
|
-
'
|
80
|
-
|
74
|
+
'value': multiply_values([urea_unspecified_as_n, urea_share]),
|
75
|
+
'factor': _urea_emission_factor('ureaKgN')
|
76
|
+
},
|
81
77
|
{
|
82
78
|
'id': 'ureaAmmoniumNitrateKgN',
|
83
|
-
'
|
84
|
-
|
85
|
-
|
86
|
-
|
79
|
+
'value': multiply_values([urea_unspecified_as_n, uan_share]),
|
80
|
+
'factor': _urea_emission_factor('ureaAmmoniumNitrateKgN')
|
81
|
+
}
|
82
|
+
] if urea_unspecified_as_n is not None else [])
|
83
|
+
|
84
|
+
has_urea_value = any([data.get('value') is not None for data in urea_values])
|
87
85
|
|
88
86
|
logRequirements(cycle, model=MODEL, term=TERM_ID,
|
87
|
+
is_term_type_fertiliser_complete=is_fertiliser_complete,
|
89
88
|
has_urea_value=has_urea_value,
|
89
|
+
urea_values=log_as_table(urea_values),
|
90
90
|
urea_unspecified_as_n=urea_unspecified_as_n,
|
91
91
|
urea_share=urea_share,
|
92
92
|
uan_share=uan_share)
|
93
93
|
|
94
|
-
should_run =
|
94
|
+
should_run = has_urea_value or is_fertiliser_complete
|
95
95
|
logShouldRun(cycle, MODEL, TERM_ID, should_run, methodTier=TIER)
|
96
96
|
return should_run, urea_values
|
97
97
|
|
98
98
|
|
99
99
|
def run(cycle: dict):
|
100
100
|
should_run, urea_values = _should_run(cycle)
|
101
|
-
return _run(
|
101
|
+
return _run(urea_values) if should_run else []
|
@@ -77,6 +77,7 @@ def _run_emission(cycle: dict, emission_term_id: str, data: dict):
|
|
77
77
|
|
78
78
|
# log run on each emission so we know it did run
|
79
79
|
details = values.get('details', {})
|
80
|
+
logShouldRun(cycle, MODEL, input_term_id, True, methodTier=TIER, emission_id=emission_term_id)
|
80
81
|
debugValues(cycle, model=model, term=emission_term_id,
|
81
82
|
value=value,
|
82
83
|
coefficient=1,
|
@@ -8,14 +8,14 @@ from hestia_earth.models.utils.input import load_impacts
|
|
8
8
|
from . import MODEL
|
9
9
|
|
10
10
|
|
11
|
-
def _indicator(term_id: str, value: float, input: dict):
|
12
|
-
indicator = _new_indicator(term_id,
|
11
|
+
def _indicator(model: str, term_id: str, value: float, input: dict):
|
12
|
+
indicator = _new_indicator(term_id, model)
|
13
13
|
indicator['value'] = value
|
14
14
|
indicator['inputs'] = [input]
|
15
15
|
return indicator
|
16
16
|
|
17
17
|
|
18
|
-
def _run_indicators(impact_assessment: dict, product: dict, term_id: str):
|
18
|
+
def _run_indicators(impact_assessment: dict, product: dict, term_id: str, model: str):
|
19
19
|
def run(values: list):
|
20
20
|
input = values[0].get('input').get('term', {})
|
21
21
|
indicator = values[0].get('indicator')
|
@@ -24,22 +24,22 @@ def _run_indicators(impact_assessment: dict, product: dict, term_id: str):
|
|
24
24
|
for value in values
|
25
25
|
])
|
26
26
|
value = convert_value_from_cycle(
|
27
|
-
impact_assessment, product, sum_values(values_from_cycle), model=
|
27
|
+
impact_assessment, product, sum_values(values_from_cycle), model=model, term_id=term_id
|
28
28
|
)
|
29
29
|
|
30
30
|
# show values per input in the logs
|
31
|
-
debugValues(impact_assessment, model=
|
31
|
+
debugValues(impact_assessment, model=model, term=term_id,
|
32
32
|
value=value,
|
33
33
|
coefficient=1,
|
34
34
|
input=input.get('@id'))
|
35
35
|
|
36
36
|
return (
|
37
|
-
_indicator(term_id, value, input) | _include(indicator, ['landCover', 'previousLandCover'])
|
37
|
+
_indicator(model, term_id, value, input) | _include(indicator, ['landCover', 'previousLandCover'])
|
38
38
|
) if value is not None else None
|
39
39
|
return run
|
40
40
|
|
41
41
|
|
42
|
-
def _run_inputs_production(impact_assessment: dict, product: dict, term_id: str):
|
42
|
+
def _run_inputs_production(impact_assessment: dict, product: dict, term_id: str, model: str):
|
43
43
|
cycle = impact_assessment.get('cycle', {})
|
44
44
|
|
45
45
|
# group all indicators per `landCover` and `previousLandCover`
|
@@ -71,7 +71,7 @@ def _run_inputs_production(impact_assessment: dict, product: dict, term_id: str)
|
|
71
71
|
])
|
72
72
|
has_indicators = bool(valid_indicators)
|
73
73
|
|
74
|
-
logRequirements(impact_assessment, model=
|
74
|
+
logRequirements(impact_assessment, model=model, term=term_id,
|
75
75
|
indicators=log_as_table([
|
76
76
|
{
|
77
77
|
'indicator-id': value.get('indicator').get('term', {}).get('@id'),
|
@@ -83,30 +83,30 @@ def _run_inputs_production(impact_assessment: dict, product: dict, term_id: str)
|
|
83
83
|
]))
|
84
84
|
|
85
85
|
should_run = all([has_indicators])
|
86
|
-
logShouldRun(impact_assessment,
|
86
|
+
logShouldRun(impact_assessment, model, term_id, should_run)
|
87
87
|
|
88
88
|
return non_empty_list(flatten(
|
89
|
-
map(_run_indicators(impact_assessment, product, term_id), grouped_indicators.values())
|
89
|
+
map(_run_indicators(impact_assessment, product, term_id, model), grouped_indicators.values())
|
90
90
|
))
|
91
91
|
|
92
92
|
|
93
|
-
def _should_run_inputs_production(impact_assessment: dict, term_id: str):
|
93
|
+
def _should_run_inputs_production(impact_assessment: dict, term_id: str, model: str):
|
94
94
|
product = get_product(impact_assessment) or {}
|
95
95
|
product_id = product.get('term', {}).get('@id')
|
96
96
|
|
97
97
|
product_value = list_sum(product.get('value', []), default=None)
|
98
98
|
economic_value = product.get('economicValueShare')
|
99
99
|
|
100
|
-
logRequirements(impact_assessment, model=
|
100
|
+
logRequirements(impact_assessment, model=model, term=term_id,
|
101
101
|
product_id=product_id,
|
102
102
|
product_value=product_value,
|
103
103
|
product_economicValueShare=economic_value)
|
104
104
|
|
105
105
|
should_run = all([product, product_value, economic_value])
|
106
|
-
logShouldRun(impact_assessment,
|
106
|
+
logShouldRun(impact_assessment, model, term_id, should_run)
|
107
107
|
return should_run, product
|
108
108
|
|
109
109
|
|
110
|
-
def run_inputs_production(impact_assessment: dict, term_id: str):
|
111
|
-
should_run, product = _should_run_inputs_production(impact_assessment, term_id)
|
112
|
-
return _run_inputs_production(impact_assessment, product, term_id) if should_run else []
|
110
|
+
def run_inputs_production(impact_assessment: dict, term_id: str, model: str = MODEL):
|
111
|
+
should_run, product = _should_run_inputs_production(impact_assessment, term_id, model)
|
112
|
+
return _run_inputs_production(impact_assessment, product, term_id, model) if should_run else []
|