hestia-earth-models 0.73.6__py3-none-any.whl → 0.73.8__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/config/Cycle.json +116 -26
- hestia_earth/models/config/ImpactAssessment.json +239 -199
- hestia_earth/models/dammgen2009/noxToAirExcreta.py +11 -9
- hestia_earth/models/ecoalimV9/cycle.py +29 -39
- hestia_earth/models/ecoalimV9/impact_assessment.py +38 -40
- hestia_earth/models/ecoalimV9/utils.py +82 -16
- hestia_earth/models/ecoinventV3/__init__.py +3 -3
- hestia_earth/models/emepEea2019/n2OToAirFuelCombustionDirect.py +2 -2
- hestia_earth/models/hestia/default_emissions.py +2 -6
- hestia_earth/models/hestia/default_resourceUse.py +2 -5
- hestia_earth/models/hestia/landCover.py +3 -3
- hestia_earth/models/hestia/pastureSystem.py +1 -1
- hestia_earth/models/hestia/seed_emissions.py +7 -3
- hestia_earth/models/impact_assessment/emissions.py +3 -5
- hestia_earth/models/ipcc2019/biocharOrganicCarbonPerHa.py +9 -3
- hestia_earth/models/ipcc2019/co2ToAirAboveGroundBiomassStockChange.py +1 -5
- hestia_earth/models/ipcc2019/co2ToAirBelowGroundBiomassStockChange.py +1 -5
- hestia_earth/models/ipcc2019/co2ToAirCarbonStockChange_utils.py +1 -33
- hestia_earth/models/ipcc2019/co2ToAirSoilOrganicCarbonStockChange.py +1 -5
- hestia_earth/models/ipcc2019/n2OToAirAquacultureSystemsIndirect.py +44 -0
- hestia_earth/models/ipcc2019/n2OToAirCropResidueBurningIndirect.py +43 -0
- hestia_earth/models/ipcc2019/n2OToAirCropResidueDecompositionIndirect.py +13 -70
- hestia_earth/models/ipcc2019/n2OToAirExcretaIndirect.py +13 -70
- hestia_earth/models/ipcc2019/n2OToAirFuelCombustionIndirect.py +43 -0
- hestia_earth/models/ipcc2019/n2OToAirInorganicFertiliserIndirect.py +13 -70
- hestia_earth/models/ipcc2019/n2OToAirNaturalVegetationBurningIndirect.py +43 -0
- hestia_earth/models/ipcc2019/n2OToAirOrganicFertiliserIndirect.py +13 -70
- hestia_earth/models/ipcc2019/n2OToAirOrganicSoilBurningIndirect.py +43 -0
- hestia_earth/models/ipcc2019/n2OToAirOrganicSoilCultivationIndirect.py +43 -0
- hestia_earth/models/ipcc2019/n2OToAir_indirect_emissions_utils.py +112 -0
- hestia_earth/models/ipcc2019/utils.py +0 -25
- hestia_earth/models/jarvisAndPain1994/n2ToAirExcreta.py +11 -9
- hestia_earth/models/linkedImpactAssessment/emissions.py +24 -15
- hestia_earth/models/linkedImpactAssessment/utils.py +5 -1
- hestia_earth/models/mocking/search-results.json +1284 -1284
- hestia_earth/models/utils/background_emissions.py +17 -10
- hestia_earth/models/utils/emission.py +18 -8
- hestia_earth/models/utils/impact_assessment.py +3 -3
- hestia_earth/models/utils/indicator.py +8 -1
- hestia_earth/models/utils/lookup.py +38 -21
- hestia_earth/models/utils/productivity.py +1 -1
- hestia_earth/models/version.py +1 -1
- hestia_earth/orchestrator/strategies/merge/merge_list.py +41 -54
- {hestia_earth_models-0.73.6.dist-info → hestia_earth_models-0.73.8.dist-info}/METADATA +3 -3
- {hestia_earth_models-0.73.6.dist-info → hestia_earth_models-0.73.8.dist-info}/RECORD +64 -49
- tests/models/dammgen2009/test_noxToAirExcreta.py +2 -2
- tests/models/ecoalimV9/test_cycle.py +1 -1
- tests/models/ecoalimV9/test_impact_assessment.py +1 -1
- tests/models/ecoalimV9/test_utils.py +13 -0
- tests/models/ipcc2019/test_biocharOrganicCarbonPerHa.py +2 -1
- tests/models/ipcc2019/test_n2OToAirAquacultureSystemsIndirect.py +45 -0
- tests/models/ipcc2019/test_n2OToAirCropResidueBurningIndirect.py +45 -0
- tests/models/ipcc2019/test_n2OToAirCropResidueDecompositionIndirect.py +6 -32
- tests/models/ipcc2019/test_n2OToAirExcretaIndirect.py +6 -32
- tests/models/ipcc2019/test_n2OToAirFuelCombustionIndirect.py +45 -0
- tests/models/ipcc2019/test_n2OToAirInorganicFertiliserIndirect.py +6 -32
- tests/models/ipcc2019/test_n2OToAirNaturalVegetationBurningIndirect.py +45 -0
- tests/models/ipcc2019/test_n2OToAirOrganicFertiliserIndirect.py +6 -32
- tests/models/ipcc2019/test_n2OToAirOrganicSoilBurningIndirect.py +45 -0
- tests/models/ipcc2019/test_n2OToAirOrganicSoilCultivationIndirect.py +45 -0
- tests/models/ipcc2019/test_n2OToAir_indirect_emissions_utils.py +19 -0
- {hestia_earth_models-0.73.6.dist-info → hestia_earth_models-0.73.8.dist-info}/LICENSE +0 -0
- {hestia_earth_models-0.73.6.dist-info → hestia_earth_models-0.73.8.dist-info}/WHEEL +0 -0
- {hestia_earth_models-0.73.6.dist-info → hestia_earth_models-0.73.8.dist-info}/top_level.txt +0 -0
|
@@ -22,7 +22,7 @@ RETURNS = {
|
|
|
22
22
|
}
|
|
23
23
|
TERM_ID = 'noxToAirExcreta'
|
|
24
24
|
TIER = EmissionMethodTier.TIER_1.value
|
|
25
|
-
|
|
25
|
+
_N2O_TERM_ID = 'n2OToAirExcretaDirect'
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
def _emission(value: float):
|
|
@@ -32,22 +32,24 @@ def _emission(value: float):
|
|
|
32
32
|
return emission
|
|
33
33
|
|
|
34
34
|
|
|
35
|
-
def _run(
|
|
36
|
-
value = 0.1 *
|
|
35
|
+
def _run(n2o_value: float):
|
|
36
|
+
value = 0.1 * n2o_value / get_atomic_conversion(Units.KG_N2O, Units.TO_N)
|
|
37
37
|
value = value * get_atomic_conversion(Units.KG_NOX, Units.TO_N)
|
|
38
38
|
return [_emission(value)]
|
|
39
39
|
|
|
40
40
|
|
|
41
41
|
def _should_run(cycle: dict):
|
|
42
|
-
n2o = find_term_match(cycle.get('emissions', []),
|
|
42
|
+
n2o = find_term_match(cycle.get('emissions', []), _N2O_TERM_ID)
|
|
43
|
+
n2o_value = list_sum(n2o.get("value", []), default=None)
|
|
43
44
|
|
|
44
|
-
logRequirements(cycle, model=MODEL, term=TERM_ID,
|
|
45
|
+
logRequirements(cycle, model=MODEL, term=TERM_ID,
|
|
46
|
+
**{_N2O_TERM_ID: n2o_value})
|
|
45
47
|
|
|
46
|
-
should_run = all([
|
|
48
|
+
should_run = all([n2o_value is not None])
|
|
47
49
|
logShouldRun(cycle, MODEL, TERM_ID, should_run, methodTier=TIER)
|
|
48
|
-
return should_run,
|
|
50
|
+
return should_run, n2o_value
|
|
49
51
|
|
|
50
52
|
|
|
51
53
|
def run(cycle: dict):
|
|
52
|
-
should_run,
|
|
53
|
-
return _run(
|
|
54
|
+
should_run, n2o_value = _should_run(cycle)
|
|
55
|
+
return _run(n2o_value) if should_run else []
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
from functools import reduce
|
|
2
2
|
from statistics import mean
|
|
3
|
-
from hestia_earth.schema import EmissionMethodTier
|
|
3
|
+
from hestia_earth.schema import EmissionMethodTier, TermTermType
|
|
4
4
|
from hestia_earth.utils.tools import flatten, list_sum
|
|
5
5
|
|
|
6
|
-
from hestia_earth.models.log import
|
|
6
|
+
from hestia_earth.models.log import logShouldRun, logRequirements
|
|
7
7
|
from hestia_earth.models.utils.emission import _new_emission
|
|
8
|
-
from hestia_earth.models.utils.background_emissions import
|
|
8
|
+
from hestia_earth.models.utils.background_emissions import (
|
|
9
|
+
get_background_inputs,
|
|
10
|
+
no_gap_filled_background_emissions,
|
|
11
|
+
log_missing_emissions
|
|
12
|
+
)
|
|
9
13
|
from hestia_earth.models.utils.blank_node import group_by_keys
|
|
10
|
-
from .utils import get_input_mappings,
|
|
14
|
+
from .utils import get_input_mappings, process_input, parse_term_id
|
|
11
15
|
from . import MODEL
|
|
12
16
|
|
|
13
17
|
REQUIREMENTS = {
|
|
@@ -46,19 +50,19 @@ RETURNS = {
|
|
|
46
50
|
}]
|
|
47
51
|
}
|
|
48
52
|
LOOKUPS = {
|
|
49
|
-
"ecoalim-
|
|
50
|
-
"crop": "ecoalimMapping",
|
|
51
|
-
"processedFood": "ecoalimMapping",
|
|
53
|
+
"ecoalim-emission": "emission-",
|
|
52
54
|
"animalProduct": "ecoalimMapping",
|
|
55
|
+
"crop": "ecoalimMapping",
|
|
56
|
+
"feedFoodAdditive": "ecoalimMapping",
|
|
53
57
|
"forage": "ecoalimMapping",
|
|
54
|
-
"
|
|
58
|
+
"processedFood": "ecoalimMapping"
|
|
55
59
|
}
|
|
56
60
|
MODEL_KEY = 'cycle'
|
|
57
61
|
TIER = EmissionMethodTier.BACKGROUND.value
|
|
58
62
|
|
|
59
63
|
|
|
60
|
-
def _emission(term_id: str, value: float, input: dict):
|
|
61
|
-
emission = _new_emission(term_id, MODEL)
|
|
64
|
+
def _emission(term_id: str, value: float, input: dict, country_id: str = None, key_id: str = None):
|
|
65
|
+
emission = _new_emission(term_id, MODEL, country_id, key_id)
|
|
62
66
|
emission['value'] = [value]
|
|
63
67
|
emission['methodTier'] = TIER
|
|
64
68
|
emission['inputs'] = [input.get('term')]
|
|
@@ -69,32 +73,9 @@ def _emission(term_id: str, value: float, input: dict):
|
|
|
69
73
|
return emission
|
|
70
74
|
|
|
71
75
|
|
|
72
|
-
def _add_emission(cycle: dict, input: dict):
|
|
73
|
-
input_term_id = input.get('term', {}).get('@id')
|
|
74
|
-
operation_term_id = input.get('operation', {}).get('@id')
|
|
75
|
-
animal_term_id = input.get('animal', {}).get('@id')
|
|
76
|
-
|
|
77
|
-
def add(prev: dict, mapping: tuple):
|
|
78
|
-
gadm_id, ecoalim_key = mapping
|
|
79
|
-
# all countries have the same coefficient
|
|
80
|
-
coefficient = 1
|
|
81
|
-
emissions = ecoalim_values(ecoalim_key, 'emission')
|
|
82
|
-
for emission_term_id, value in emissions:
|
|
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)
|
|
85
|
-
debugValues(cycle, model=MODEL, term=emission_term_id, model_key=MODEL_KEY,
|
|
86
|
-
value=value,
|
|
87
|
-
coefficient=coefficient,
|
|
88
|
-
input=input_term_id,
|
|
89
|
-
operation=operation_term_id,
|
|
90
|
-
animal=animal_term_id)
|
|
91
|
-
prev[emission_term_id] = prev.get(emission_term_id, []) + [value * coefficient]
|
|
92
|
-
return prev
|
|
93
|
-
return add
|
|
94
|
-
|
|
95
|
-
|
|
96
76
|
def _run_input(cycle: dict):
|
|
97
77
|
no_gap_filled_background_emissions_func = no_gap_filled_background_emissions(cycle)
|
|
78
|
+
log_missing_emissions_func = log_missing_emissions(cycle, model=MODEL, methodTier=TIER)
|
|
98
79
|
|
|
99
80
|
def run(inputs: list):
|
|
100
81
|
input = inputs[0]
|
|
@@ -107,18 +88,27 @@ def _run_input(cycle: dict):
|
|
|
107
88
|
has_no_gap_filled_background_emissions = no_gap_filled_background_emissions_func(input)
|
|
108
89
|
|
|
109
90
|
logRequirements(cycle, model=MODEL, term=input_term_id, model_key=MODEL_KEY,
|
|
110
|
-
|
|
111
|
-
|
|
91
|
+
has_mappings=has_mappings,
|
|
92
|
+
mappings=';'.join([v[1] for v in mappings]),
|
|
112
93
|
has_no_gap_filled_background_emissions=has_no_gap_filled_background_emissions,
|
|
113
94
|
input_value=input_value)
|
|
114
95
|
|
|
115
96
|
should_run = all([has_mappings, has_no_gap_filled_background_emissions, input_value])
|
|
116
97
|
logShouldRun(cycle, MODEL, input_term_id, should_run, methodTier=TIER, model_key=MODEL_KEY)
|
|
117
98
|
|
|
118
|
-
|
|
99
|
+
results = process_input(
|
|
100
|
+
cycle, input, mappings, TermTermType.EMISSION, model_key=MODEL_KEY
|
|
101
|
+
) if should_run else {}
|
|
102
|
+
log_missing_emissions_func(input_term_id, list(map(parse_term_id, results.keys())))
|
|
119
103
|
return [
|
|
120
|
-
_emission(
|
|
121
|
-
|
|
104
|
+
_emission(
|
|
105
|
+
term_id=parse_term_id(term_id),
|
|
106
|
+
value=mean([v['value'] * v['coefficient'] for v in values]) * input_value,
|
|
107
|
+
input=input,
|
|
108
|
+
country_id=values[0].get('country'),
|
|
109
|
+
key_id=values[0].get('key'),
|
|
110
|
+
)
|
|
111
|
+
for term_id, values in results.items()
|
|
122
112
|
]
|
|
123
113
|
return run
|
|
124
114
|
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
from functools import reduce
|
|
2
2
|
from statistics import mean
|
|
3
|
-
from hestia_earth.schema import IndicatorMethodTier
|
|
3
|
+
from hestia_earth.schema import IndicatorMethodTier, TermTermType
|
|
4
4
|
from hestia_earth.utils.tools import flatten, list_sum
|
|
5
5
|
|
|
6
|
-
from hestia_earth.models.log import
|
|
6
|
+
from hestia_earth.models.log import logShouldRun, logRequirements
|
|
7
7
|
from hestia_earth.models.utils.indicator import _new_indicator
|
|
8
|
-
from hestia_earth.models.utils.background_emissions import get_background_inputs
|
|
8
|
+
from hestia_earth.models.utils.background_emissions import get_background_inputs, log_missing_emissions
|
|
9
9
|
from hestia_earth.models.utils.blank_node import group_by_keys
|
|
10
|
-
from .utils import get_input_mappings,
|
|
10
|
+
from .utils import get_input_mappings, process_input, parse_term_id
|
|
11
11
|
from . import MODEL
|
|
12
12
|
|
|
13
13
|
REQUIREMENTS = {
|
|
@@ -48,19 +48,27 @@ RETURNS = {
|
|
|
48
48
|
}]
|
|
49
49
|
}
|
|
50
50
|
LOOKUPS = {
|
|
51
|
-
"ecoalim-
|
|
52
|
-
"crop": "ecoalimMapping",
|
|
53
|
-
"processedFood": "ecoalimMapping",
|
|
51
|
+
"ecoalim-resourceUse": "resourceUse-",
|
|
54
52
|
"animalProduct": "ecoalimMapping",
|
|
53
|
+
"crop": "ecoalimMapping",
|
|
54
|
+
"feedFoodAdditive": "ecoalimMapping",
|
|
55
55
|
"forage": "ecoalimMapping",
|
|
56
|
-
"
|
|
56
|
+
"processedFood": "ecoalimMapping"
|
|
57
57
|
}
|
|
58
58
|
MODEL_KEY = 'impact_assessment'
|
|
59
59
|
TIER = IndicatorMethodTier.BACKGROUND.value
|
|
60
60
|
|
|
61
61
|
|
|
62
|
-
def _indicator(
|
|
63
|
-
|
|
62
|
+
def _indicator(
|
|
63
|
+
term_id: str,
|
|
64
|
+
value: float,
|
|
65
|
+
input: dict,
|
|
66
|
+
country_id: str = None,
|
|
67
|
+
key_id: str = None,
|
|
68
|
+
land_cover_id: str = None,
|
|
69
|
+
previous_land_cover_id: str = None,
|
|
70
|
+
):
|
|
71
|
+
indicator = _new_indicator(term_id, MODEL, land_cover_id, previous_land_cover_id, country_id, key_id)
|
|
64
72
|
indicator['value'] = value
|
|
65
73
|
indicator['methodTier'] = TIER
|
|
66
74
|
indicator['inputs'] = [input.get('term')]
|
|
@@ -69,32 +77,11 @@ def _indicator(term_id: str, value: float, input: dict):
|
|
|
69
77
|
return indicator
|
|
70
78
|
|
|
71
79
|
|
|
72
|
-
def _add_indicator(cycle: dict, input: dict):
|
|
73
|
-
input_term_id = input.get('term', {}).get('@id')
|
|
74
|
-
operation_term_id = input.get('operation', {}).get('@id')
|
|
75
|
-
animal_term_id = input.get('animal', {}).get('@id')
|
|
76
|
-
|
|
77
|
-
def add(prev: dict, mapping: tuple):
|
|
78
|
-
gadm_id, ecoalim_key = mapping
|
|
79
|
-
# all countries have the same coefficient
|
|
80
|
-
coefficient = 1
|
|
81
|
-
indicators = ecoalim_values(ecoalim_key, 'resourceUse')
|
|
82
|
-
for indicator_term_id, value in indicators:
|
|
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)
|
|
85
|
-
debugValues(cycle, model=MODEL, term=indicator_term_id, model_key=MODEL_KEY,
|
|
86
|
-
value=value,
|
|
87
|
-
coefficient=coefficient,
|
|
88
|
-
input=input_term_id,
|
|
89
|
-
operation=operation_term_id,
|
|
90
|
-
animal=animal_term_id)
|
|
91
|
-
if value is not None:
|
|
92
|
-
prev[indicator_term_id] = prev.get(indicator_term_id, []) + [value * coefficient]
|
|
93
|
-
return prev
|
|
94
|
-
return add
|
|
95
|
-
|
|
96
|
-
|
|
97
80
|
def _run_input(impact_assessment: dict):
|
|
81
|
+
log_missing_emissions_func = log_missing_emissions(
|
|
82
|
+
impact_assessment, TermTermType.RESOURCEUSE, model=MODEL, methodTier=TIER
|
|
83
|
+
)
|
|
84
|
+
|
|
98
85
|
def run(inputs: list):
|
|
99
86
|
input = inputs[0]
|
|
100
87
|
input_term_id = input.get('term', {}).get('@id')
|
|
@@ -103,8 +90,8 @@ def _run_input(impact_assessment: dict):
|
|
|
103
90
|
has_mappings = len(mappings) > 0
|
|
104
91
|
|
|
105
92
|
logRequirements(impact_assessment, model=MODEL, term=input_term_id, model_key=MODEL_KEY,
|
|
106
|
-
|
|
107
|
-
|
|
93
|
+
has_mappings=has_mappings,
|
|
94
|
+
mappings=';'.join([v[1] for v in mappings]),
|
|
108
95
|
input_value=input_value)
|
|
109
96
|
|
|
110
97
|
should_run = all([has_mappings, input_value])
|
|
@@ -112,10 +99,21 @@ def _run_input(impact_assessment: dict):
|
|
|
112
99
|
impact_assessment, MODEL, input_term_id, should_run, methodTier=TIER, model_key=MODEL_KEY
|
|
113
100
|
)
|
|
114
101
|
|
|
115
|
-
|
|
102
|
+
results = process_input(
|
|
103
|
+
impact_assessment, input, mappings, TermTermType.RESOURCEUSE, model_key=MODEL_KEY
|
|
104
|
+
) if should_run else {}
|
|
105
|
+
log_missing_emissions_func(input_term_id, list(map(parse_term_id, results.keys())))
|
|
116
106
|
return [
|
|
117
|
-
_indicator(
|
|
118
|
-
|
|
107
|
+
_indicator(
|
|
108
|
+
term_id=parse_term_id(term_id),
|
|
109
|
+
value=mean([v['value'] * v['coefficient'] for v in values]) * input_value,
|
|
110
|
+
input=input,
|
|
111
|
+
country_id=values[0].get('country'),
|
|
112
|
+
key_id=values[0].get('key'),
|
|
113
|
+
land_cover_id=values[0].get('landCover'),
|
|
114
|
+
previous_land_cover_id=values[0].get('previousLandCover'),
|
|
115
|
+
)
|
|
116
|
+
for term_id, values in results.items()
|
|
119
117
|
]
|
|
120
118
|
return run
|
|
121
119
|
|
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
from
|
|
2
|
-
from hestia_earth.
|
|
1
|
+
from functools import lru_cache, reduce
|
|
2
|
+
from hestia_earth.schema import EmissionMethodTier, TermTermType
|
|
3
|
+
from hestia_earth.utils.lookup import download_lookup, _is_missing_value, column_name, lookup_columns
|
|
4
|
+
from hestia_earth.utils.tools import non_empty_list, safe_parse_float
|
|
3
5
|
|
|
6
|
+
from hestia_earth.models.log import debugValues, logShouldRun
|
|
7
|
+
from hestia_earth.models.utils import _omit
|
|
4
8
|
from hestia_earth.models.utils.term import get_lookup_value
|
|
9
|
+
from . import MODEL
|
|
5
10
|
|
|
6
|
-
|
|
7
|
-
|
|
11
|
+
_LOOKUP_INDEX_KEY = column_name('ecoalimMappingName')
|
|
12
|
+
_TIER = EmissionMethodTier.BACKGROUND.value
|
|
8
13
|
|
|
9
14
|
|
|
10
15
|
def get_input_mappings(model: str, input: dict):
|
|
@@ -15,17 +20,78 @@ def get_input_mappings(model: str, input: dict):
|
|
|
15
20
|
return [(m.split(':')[0], m.split(':')[1]) for m in mappings]
|
|
16
21
|
|
|
17
22
|
|
|
18
|
-
def
|
|
19
|
-
|
|
20
|
-
|
|
23
|
+
def parse_term_id(term_id: str): return term_id.split('-')[0]
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _process_mapping(node: dict, input: dict, term_type: TermTermType, **log_args):
|
|
27
|
+
input_term_id = input.get('term', {}).get('@id')
|
|
28
|
+
operation_term_id = input.get('operation', {}).get('@id')
|
|
29
|
+
animal_term_id = input.get('animal', {}).get('@id')
|
|
30
|
+
|
|
31
|
+
def add(prev: dict, mapping: tuple):
|
|
32
|
+
gadm_id, ecoalim_key = mapping
|
|
33
|
+
# all countries have the same coefficient
|
|
34
|
+
coefficient = 1
|
|
35
|
+
values = ecoalim_values(ecoalim_key, term_type)
|
|
36
|
+
for term_id, data in values:
|
|
37
|
+
# log run on each node so we know it did run
|
|
38
|
+
logShouldRun(node, MODEL, input_term_id, True, methodTier=_TIER, emission_id=term_id)
|
|
39
|
+
debugValues(node, model=MODEL, term=term_id,
|
|
40
|
+
value=data.get('value'),
|
|
41
|
+
coefficient=coefficient,
|
|
42
|
+
input=input_term_id,
|
|
43
|
+
operation=operation_term_id,
|
|
44
|
+
animal=animal_term_id,
|
|
45
|
+
**log_args)
|
|
46
|
+
group_id = '-'.join(non_empty_list([term_id] + list(_omit(data, ['value']).values())))
|
|
47
|
+
prev[group_id] = prev.get(group_id, []) + [data | {'coefficient': coefficient}]
|
|
48
|
+
return prev
|
|
49
|
+
return add
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def process_input(node: dict, input: dict, mappings: list, term_type: TermTermType, **log_args):
|
|
53
|
+
return reduce(_process_mapping(node, input, term_type, **log_args), mappings, {})
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
_KEY_TO_FIELD = {
|
|
57
|
+
'inputs': 'key'
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def _key_to_field(key: str): return _KEY_TO_FIELD.get(key) or key
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def _values_from_column(column: str, value: str):
|
|
65
|
+
values = column.split('+')
|
|
66
|
+
term_id = values[0]
|
|
67
|
+
value = safe_parse_float(value, default=None)
|
|
68
|
+
return {
|
|
69
|
+
term_id: {
|
|
70
|
+
'value': value
|
|
71
|
+
} | {
|
|
72
|
+
_key_to_field(v.split('[')[0]): v.split('[')[1][:-1] for v in values[1:]
|
|
73
|
+
}
|
|
74
|
+
} if all([
|
|
75
|
+
column != _LOOKUP_INDEX_KEY,
|
|
76
|
+
not _is_missing_value(value)
|
|
77
|
+
]) else {}
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
@lru_cache()
|
|
81
|
+
def _build_lookup(term_type: str):
|
|
82
|
+
lookup = download_lookup(f"ecoalim-{term_type}.csv", keep_in_memory=False)
|
|
83
|
+
columns = lookup_columns(lookup)
|
|
84
|
+
return {
|
|
85
|
+
row[_LOOKUP_INDEX_KEY]: reduce(
|
|
86
|
+
lambda prev, curr: prev | _values_from_column(curr, row[curr]),
|
|
87
|
+
columns,
|
|
88
|
+
{}
|
|
89
|
+
)
|
|
90
|
+
for row in lookup
|
|
91
|
+
}
|
|
21
92
|
|
|
22
|
-
def emission(column: str):
|
|
23
|
-
id = get_table_value(lookup, col_name, mapping, column)
|
|
24
|
-
value = get_table_value(lookup, col_name, mapping, column.replace('term', 'value'))
|
|
25
|
-
return (id, value) if id else None
|
|
26
93
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
]
|
|
31
|
-
return non_empty_list(map(emission, columns))
|
|
94
|
+
@lru_cache()
|
|
95
|
+
def ecoalim_values(mapping: str, term_type: TermTermType):
|
|
96
|
+
data = _build_lookup(term_type.value)
|
|
97
|
+
return list(data[mapping].items())
|
|
@@ -129,11 +129,11 @@ def _run_input(cycle: dict):
|
|
|
129
129
|
should_run = all([has_mappings, has_no_gap_filled_background_emissions, input_value])
|
|
130
130
|
logShouldRun(cycle, MODEL, input_term_id, should_run, methodTier=TIER, **extra_logs)
|
|
131
131
|
|
|
132
|
-
|
|
133
|
-
log_missing_emissions_func(input_term_id, list(
|
|
132
|
+
results = reduce(_add_emission(cycle, input, **extra_logs), mappings, {}) if should_run else {}
|
|
133
|
+
log_missing_emissions_func(input_term_id, list(results.keys()), **extra_logs)
|
|
134
134
|
return [
|
|
135
135
|
_emission(term_id, value * input_value, input)
|
|
136
|
-
for term_id, value in
|
|
136
|
+
for term_id, value in results.items()
|
|
137
137
|
]
|
|
138
138
|
return run
|
|
139
139
|
|
|
@@ -26,8 +26,8 @@ RETURNS = {
|
|
|
26
26
|
}]
|
|
27
27
|
}
|
|
28
28
|
LOOKUPS = {
|
|
29
|
-
"fuel": "
|
|
30
|
-
"operation": "
|
|
29
|
+
"fuel": "n2oToAirFuelCombustionEmepEea2019",
|
|
30
|
+
"operation": "n2oToAirFuelCombustionEmepEea2019"
|
|
31
31
|
}
|
|
32
32
|
TERM_ID = 'n2OToAirFuelCombustionDirect'
|
|
33
33
|
TIER = EmissionMethodTier.TIER_1.value
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
from hestia_earth.schema import EmissionMethodTier
|
|
2
2
|
from hestia_earth.utils.tools import flatten, safe_parse_float
|
|
3
|
-
from hestia_earth.utils.emission import cycle_emissions_in_system_boundary
|
|
4
3
|
|
|
5
4
|
from hestia_earth.models.log import logRequirements, logShouldRun
|
|
6
5
|
from hestia_earth.models.utils import _omit
|
|
7
|
-
from hestia_earth.models.utils.emission import _new_emission
|
|
6
|
+
from hestia_earth.models.utils.emission import _new_emission, background_emissions_in_system_boundary
|
|
8
7
|
from hestia_earth.models.utils.background_emissions import no_gap_filled_background_emissions
|
|
9
8
|
from hestia_earth.models.utils.term import get_lookup_value
|
|
10
9
|
from hestia_earth.models.utils.input import unique_background_inputs
|
|
@@ -51,10 +50,7 @@ def _default_value(input: dict):
|
|
|
51
50
|
|
|
52
51
|
|
|
53
52
|
def _run_input(cycle: dict):
|
|
54
|
-
required_emission_term_ids =
|
|
55
|
-
id for id in cycle_emissions_in_system_boundary(cycle)
|
|
56
|
-
if id.endswith('InputsProduction')
|
|
57
|
-
]
|
|
53
|
+
required_emission_term_ids = background_emissions_in_system_boundary(cycle)
|
|
58
54
|
|
|
59
55
|
def run(input: dict):
|
|
60
56
|
input_term = input.get('input').get('term')
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
from hestia_earth.schema import IndicatorMethodTier, TermTermType
|
|
2
2
|
from hestia_earth.utils.tools import flatten, safe_parse_float
|
|
3
|
-
from hestia_earth.utils.emission import emissions_in_system_boundary
|
|
4
3
|
|
|
5
4
|
from hestia_earth.models.log import logRequirements, logShouldRun
|
|
6
5
|
from hestia_earth.models.utils import _omit
|
|
6
|
+
from hestia_earth.models.utils.emission import background_emissions_in_system_boundary
|
|
7
7
|
from hestia_earth.models.utils.indicator import _new_indicator
|
|
8
8
|
from hestia_earth.models.utils.background_emissions import no_gap_filled_background_emissions
|
|
9
9
|
from hestia_earth.models.utils.term import get_lookup_value
|
|
@@ -54,10 +54,7 @@ def _default_value(input: dict):
|
|
|
54
54
|
|
|
55
55
|
|
|
56
56
|
def _run_input(impact: dict):
|
|
57
|
-
required_resourceUse_term_ids =
|
|
58
|
-
id for id in emissions_in_system_boundary(TermTermType.RESOURCEUSE)
|
|
59
|
-
if id.endswith('InputsProduction')
|
|
60
|
-
]
|
|
57
|
+
required_resourceUse_term_ids = background_emissions_in_system_boundary(impact, TermTermType.RESOURCEUSE)
|
|
61
58
|
|
|
62
59
|
def run(input: dict):
|
|
63
60
|
input_term = input.get('input').get('term')
|
|
@@ -14,7 +14,7 @@ from hestia_earth.models.utils import _omit
|
|
|
14
14
|
from hestia_earth.models.utils.constant import DAYS_IN_YEAR
|
|
15
15
|
from hestia_earth.models.utils.management import _new_management
|
|
16
16
|
from hestia_earth.models.utils.term import get_lookup_value
|
|
17
|
-
from hestia_earth.models.utils.lookup import get_region_lookup_value
|
|
17
|
+
from hestia_earth.models.utils.lookup import get_region_lookup, get_region_lookup_value
|
|
18
18
|
from hestia_earth.models.utils.blank_node import DatestrFormat, _gapfill_datestr, DatestrGapfillMode
|
|
19
19
|
from .utils import (
|
|
20
20
|
IPCC_LAND_USE_CATEGORY_ANNUAL,
|
|
@@ -586,10 +586,10 @@ def _get_sums_of_crop_expansion(country_id: str, year: int, include_negatives: b
|
|
|
586
586
|
Sum net expansion for all annual and permanent crops, returned as two values.
|
|
587
587
|
Returns a tuple of (expansion of annual crops, expansion of permanent crops)
|
|
588
588
|
"""
|
|
589
|
-
lookup =
|
|
589
|
+
lookup = get_region_lookup(lookup_name=_LOOKUP_EXPANSION, term_id=country_id)
|
|
590
590
|
columns = lookup_columns(lookup)
|
|
591
591
|
values = {
|
|
592
|
-
name:
|
|
592
|
+
name: get_table_value(lookup, 'termid', country_id, column_name(name))
|
|
593
593
|
for name in columns if name != "termid"
|
|
594
594
|
}
|
|
595
595
|
|
|
@@ -41,7 +41,7 @@ def _practice(term_id: str):
|
|
|
41
41
|
def _run(cycle: dict):
|
|
42
42
|
end_date = cycle.get('endDate')
|
|
43
43
|
measurements = cycle.get('site', {}).get('measurements', [])
|
|
44
|
-
slope = measurement_value(most_relevant_blank_node_by_id(measurements, 'slope', end_date))
|
|
44
|
+
slope = measurement_value(most_relevant_blank_node_by_id(measurements, 'slope', end_date), default=0)
|
|
45
45
|
term_id = 'confinedPastureSystem' if slope <= 2.5 else 'hillyPastureSystem'
|
|
46
46
|
|
|
47
47
|
debugValues(cycle, model=MODEL, term=term_id,
|
|
@@ -109,10 +109,11 @@ def _map_group_emissions(group_id: str, required_emission_term_ids: list, emissi
|
|
|
109
109
|
missing_emissions = list(filter(lambda v: v not in emission_ids, emissions))
|
|
110
110
|
return {
|
|
111
111
|
'group-id': group_id,
|
|
112
|
+
'is-group-in-system-boundary': group_id in required_emission_term_ids,
|
|
112
113
|
'total-emissions': len(emissions),
|
|
113
114
|
'included-emissions': len(included_emissions),
|
|
114
115
|
'missing-emissions': '-'.join(missing_emissions),
|
|
115
|
-
'
|
|
116
|
+
'has-all-emissions': len(emissions) == len(included_emissions)
|
|
116
117
|
}
|
|
117
118
|
|
|
118
119
|
|
|
@@ -140,7 +141,10 @@ def _filter_emissions(cycle: dict):
|
|
|
140
141
|
for group_id in group_ids
|
|
141
142
|
]
|
|
142
143
|
# only keep groups that have all emissions present in the Cycle
|
|
143
|
-
valid_groups = list(filter(lambda group:
|
|
144
|
+
valid_groups = list(filter(lambda group: all([
|
|
145
|
+
group.get('has-all-emissions'),
|
|
146
|
+
group.get('is-group-in-system-boundary')
|
|
147
|
+
]), emissions_per_group))
|
|
144
148
|
valid_group_ids = set([v.get('group-id') for v in valid_groups])
|
|
145
149
|
|
|
146
150
|
# finally, only return emissions which groups are valid
|
|
@@ -283,7 +287,7 @@ def _should_run(cycle: dict):
|
|
|
283
287
|
# log failed emissions to show in the logs
|
|
284
288
|
for group in emissions_per_group:
|
|
285
289
|
emission_id = group.get('group-id')
|
|
286
|
-
if not group.get('
|
|
290
|
+
if not group.get('has-all-emissions') or not should_run:
|
|
287
291
|
logRequirements(cycle, model=MODEL, term=term_id, model_key=MODEL_KEY, emission_id=emission_id,
|
|
288
292
|
**group,
|
|
289
293
|
**_omit(seed_input, 'input'),
|
|
@@ -2,6 +2,7 @@ from hestia_earth.utils.tools import list_sum
|
|
|
2
2
|
from hestia_earth.utils.emission import cycle_emissions_in_system_boundary
|
|
3
3
|
|
|
4
4
|
from hestia_earth.models.log import logRequirements, logShouldRun
|
|
5
|
+
from hestia_earth.models.utils import _include
|
|
5
6
|
from hestia_earth.models.utils.impact_assessment import get_product, convert_value_from_cycle
|
|
6
7
|
from hestia_earth.models.utils.indicator import _new_indicator
|
|
7
8
|
from . import MODEL
|
|
@@ -44,11 +45,8 @@ def _indicator(impact_assessment: dict, product: dict):
|
|
|
44
45
|
|
|
45
46
|
if len(emission.get('inputs', [])):
|
|
46
47
|
indicator['inputs'] = emission['inputs']
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
if emission.get('transformation'):
|
|
50
|
-
indicator['transformation'] = emission.get('transformation')
|
|
51
|
-
return indicator
|
|
48
|
+
|
|
49
|
+
return indicator | _include(emission, ['operation', 'transformation', 'country', 'key'])
|
|
52
50
|
return run
|
|
53
51
|
|
|
54
52
|
|
|
@@ -57,12 +57,16 @@ RETURNS = {
|
|
|
57
57
|
"statsDefinition": "simulated",
|
|
58
58
|
"observations": "",
|
|
59
59
|
"dates": "",
|
|
60
|
+
"depthUpper": "",
|
|
61
|
+
"depthLower": "",
|
|
60
62
|
"methodClassification": "tier 1 model"
|
|
61
63
|
}]
|
|
62
64
|
}
|
|
63
65
|
TERM_ID = 'biocharOrganicCarbonPerHa'
|
|
64
66
|
|
|
65
67
|
_ITERATIONS = 1000
|
|
68
|
+
_DEPTH_UPPER = 0
|
|
69
|
+
_DEPTH_LOWER = 30
|
|
66
70
|
_METHOD_CLASSIFICATION = MeasurementMethodClassification.TIER_1_MODEL.value
|
|
67
71
|
_STATS_DEFINITION = MeasurementStatsDefinition.SIMULATED.value
|
|
68
72
|
|
|
@@ -172,7 +176,7 @@ def _compile_inventory(
|
|
|
172
176
|
cycle_data = {
|
|
173
177
|
cycle.get("@id"): {
|
|
174
178
|
"biochar_nodes": filter_list_term_type(cycle.get("inputs", []), TermTermType.BIOCHAR),
|
|
175
|
-
**{
|
|
179
|
+
**{k: v for k in COPY_FIELDS if (v := cycle.get(k)) is not None}
|
|
176
180
|
} for cycle in cycles
|
|
177
181
|
}
|
|
178
182
|
|
|
@@ -201,7 +205,7 @@ def _compile_inventory(
|
|
|
201
205
|
[
|
|
202
206
|
{
|
|
203
207
|
"total_oc": total_oc.get(id, 0),
|
|
204
|
-
**
|
|
208
|
+
**data
|
|
205
209
|
} for id, data in cycle_data.items()
|
|
206
210
|
],
|
|
207
211
|
include_spillovers=True
|
|
@@ -427,9 +431,11 @@ def _measurement(
|
|
|
427
431
|
"statsDefinition": statsDefinition,
|
|
428
432
|
"observations": observations,
|
|
429
433
|
"dates": dates,
|
|
434
|
+
"depthUpper": _DEPTH_UPPER,
|
|
435
|
+
"depthLower": _DEPTH_LOWER,
|
|
430
436
|
"methodClassification": _METHOD_CLASSIFICATION
|
|
431
437
|
}
|
|
432
438
|
measurement = _new_measurement(TERM_ID, MODEL) | {
|
|
433
|
-
key: value for key, value in update_dict.items() if value
|
|
439
|
+
key: value for key, value in update_dict.items() if value is not None
|
|
434
440
|
}
|
|
435
441
|
return measurement
|
|
@@ -78,9 +78,7 @@ def _emission(
|
|
|
78
78
|
min: list[float] = None,
|
|
79
79
|
max: list[float] = None,
|
|
80
80
|
statsDefinition: str = None,
|
|
81
|
-
observations: list[int] = None
|
|
82
|
-
start_date: str,
|
|
83
|
-
end_date: str
|
|
81
|
+
observations: list[int] = None
|
|
84
82
|
) -> dict:
|
|
85
83
|
"""
|
|
86
84
|
Create an emission node based on the provided value and method tier.
|
|
@@ -108,8 +106,6 @@ def _emission(
|
|
|
108
106
|
"max": max,
|
|
109
107
|
"statsDefinition": statsDefinition,
|
|
110
108
|
"observations": observations,
|
|
111
|
-
"startDate": start_date,
|
|
112
|
-
"endDate": end_date,
|
|
113
109
|
"methodTier": method_tier.value,
|
|
114
110
|
}
|
|
115
111
|
emission = _new_emission(term_id, MODEL) | {
|
|
@@ -69,9 +69,7 @@ def _emission(
|
|
|
69
69
|
min: list[float] = None,
|
|
70
70
|
max: list[float] = None,
|
|
71
71
|
statsDefinition: str = None,
|
|
72
|
-
observations: list[int] = None
|
|
73
|
-
start_date: str,
|
|
74
|
-
end_date: str
|
|
72
|
+
observations: list[int] = None
|
|
75
73
|
) -> dict:
|
|
76
74
|
"""
|
|
77
75
|
Create an emission node based on the provided value and method tier.
|
|
@@ -99,8 +97,6 @@ def _emission(
|
|
|
99
97
|
"max": max,
|
|
100
98
|
"statsDefinition": statsDefinition,
|
|
101
99
|
"observations": observations,
|
|
102
|
-
"startDate": start_date,
|
|
103
|
-
"endDate": end_date,
|
|
104
100
|
"methodTier": method_tier.value,
|
|
105
101
|
"depth": _DEPTH_LOWER
|
|
106
102
|
}
|