hestia-earth-aggregation 0.21.16__tar.gz → 0.21.17__tar.gz
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_aggregation-0.21.16/hestia_earth_aggregation.egg-info → hestia_earth_aggregation-0.21.17}/PKG-INFO +1 -1
- hestia_earth_aggregation-0.21.17/hestia_earth/aggregation/config/Cycle/processedFood.json +63 -0
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/hestia_earth/aggregation/recalculate_cycles.py +2 -1
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/hestia_earth/aggregation/utils/aggregate_country_nodes.py +6 -1
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/hestia_earth/aggregation/utils/cycle.py +2 -4
- hestia_earth_aggregation-0.21.17/hestia_earth/aggregation/utils/emission.py +82 -0
- hestia_earth_aggregation-0.21.17/hestia_earth/aggregation/version.py +1 -0
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17/hestia_earth_aggregation.egg-info}/PKG-INFO +1 -1
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/hestia_earth_aggregation.egg-info/SOURCES.txt +1 -0
- hestia_earth_aggregation-0.21.16/hestia_earth/aggregation/utils/emission.py +0 -86
- hestia_earth_aggregation-0.21.16/hestia_earth/aggregation/version.py +0 -1
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/LICENSE +0 -0
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/MANIFEST.in +0 -0
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/README.md +0 -0
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/hestia_earth/aggregation/__init__.py +0 -0
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/hestia_earth/aggregation/aggregate_cycles.py +0 -0
- /hestia_earth_aggregation-0.21.16/hestia_earth/aggregation/config/Cycle/processedFood.json → /hestia_earth_aggregation-0.21.17/hestia_earth/aggregation/config/Cycle/crop.json +0 -0
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/hestia_earth/aggregation/log.py +0 -0
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/hestia_earth/aggregation/utils/__init__.py +0 -0
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/hestia_earth/aggregation/utils/aggregate_weighted.py +0 -0
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/hestia_earth/aggregation/utils/blank_node.py +0 -0
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/hestia_earth/aggregation/utils/combine.py +0 -0
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/hestia_earth/aggregation/utils/completeness.py +0 -0
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/hestia_earth/aggregation/utils/covariance.py +0 -0
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/hestia_earth/aggregation/utils/distribution.py +0 -0
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/hestia_earth/aggregation/utils/group.py +0 -0
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/hestia_earth/aggregation/utils/input.py +0 -0
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/hestia_earth/aggregation/utils/lookup.py +0 -0
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/hestia_earth/aggregation/utils/management.py +0 -0
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/hestia_earth/aggregation/utils/measurement.py +0 -0
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/hestia_earth/aggregation/utils/practice.py +0 -0
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/hestia_earth/aggregation/utils/product.py +0 -0
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/hestia_earth/aggregation/utils/property.py +0 -0
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/hestia_earth/aggregation/utils/quality_score.py +0 -0
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/hestia_earth/aggregation/utils/queries.py +0 -0
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/hestia_earth/aggregation/utils/site.py +0 -0
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/hestia_earth/aggregation/utils/source.py +0 -0
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/hestia_earth/aggregation/utils/term.py +0 -0
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/hestia_earth/aggregation/utils/weights.py +0 -0
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/hestia_earth_aggregation.egg-info/dependency_links.txt +0 -0
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/hestia_earth_aggregation.egg-info/requires.txt +0 -0
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/hestia_earth_aggregation.egg-info/top_level.txt +0 -0
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/setup.cfg +0 -0
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/setup.py +0 -0
- {hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/tests/test_aggregation.py +0 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"models": [
|
|
3
|
+
{
|
|
4
|
+
"key": "inputs",
|
|
5
|
+
"model": "cycle",
|
|
6
|
+
"value": "input.hestiaAggregatedData",
|
|
7
|
+
"runStrategy": "always",
|
|
8
|
+
"mergeStrategy": "list"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"key": "emissions",
|
|
12
|
+
"model": "linkedImpactAssessment",
|
|
13
|
+
"value": "emissions",
|
|
14
|
+
"runStrategy": "always",
|
|
15
|
+
"mergeStrategy": "list",
|
|
16
|
+
"mergeArgs": {
|
|
17
|
+
"replaceThreshold": ["value", 0.01]
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"key": "emissions",
|
|
22
|
+
"model": "ecoalimV9",
|
|
23
|
+
"value": "cycle",
|
|
24
|
+
"runStrategy": "always",
|
|
25
|
+
"mergeStrategy": "list",
|
|
26
|
+
"mergeArgs": {
|
|
27
|
+
"replaceThreshold": ["value", 0.01]
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"key": "emissions",
|
|
32
|
+
"model": "worldSteel",
|
|
33
|
+
"value": "cycle",
|
|
34
|
+
"runStrategy": "always",
|
|
35
|
+
"mergeStrategy": "list",
|
|
36
|
+
"mergeArgs": {
|
|
37
|
+
"replaceThreshold": ["value", 0.01]
|
|
38
|
+
},
|
|
39
|
+
"stage": 2
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"key": "emissions",
|
|
43
|
+
"model": "bafu2025",
|
|
44
|
+
"value": "cycle",
|
|
45
|
+
"runStrategy": "always",
|
|
46
|
+
"mergeStrategy": "list",
|
|
47
|
+
"mergeArgs": {
|
|
48
|
+
"replaceThreshold": ["value", 0.01]
|
|
49
|
+
},
|
|
50
|
+
"stage": 2
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
"key": "emissions",
|
|
54
|
+
"model": "ecoinventV3AndEmberClimate",
|
|
55
|
+
"value": "cycle",
|
|
56
|
+
"runStrategy": "always",
|
|
57
|
+
"mergeStrategy": "list",
|
|
58
|
+
"mergeArgs": {
|
|
59
|
+
"replaceThreshold": ["value", 0.01]
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
]
|
|
63
|
+
}
|
|
@@ -4,10 +4,11 @@ from hestia_earth.orchestrator import run
|
|
|
4
4
|
|
|
5
5
|
CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
6
6
|
CONFIG_PATH = os.path.join(CURRENT_DIR, "config", "Cycle")
|
|
7
|
+
_TERM_TYPES = os.listdir(CONFIG_PATH)
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
def should_recalculate(product: dict):
|
|
10
|
-
return f"{product.get('termType')}.json" in
|
|
11
|
+
return f"{product.get('termType')}.json" in _TERM_TYPES
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
def recalculate(cycle: dict, product: dict):
|
|
@@ -65,6 +65,7 @@ from .emission import (
|
|
|
65
65
|
get_method_tier,
|
|
66
66
|
get_method_model,
|
|
67
67
|
has_value_without_transformation,
|
|
68
|
+
include_emission,
|
|
68
69
|
)
|
|
69
70
|
from .property import aggregate_properties
|
|
70
71
|
from .distribution import generate_blank_node_distribution
|
|
@@ -205,6 +206,10 @@ def _group_cycle_blank_node(cycle: dict, product: dict, product_value: float):
|
|
|
205
206
|
term_id = term.get("@id")
|
|
206
207
|
group_key = blank_node_group_key(blank_node)
|
|
207
208
|
|
|
209
|
+
# skip background emissions when recalculated
|
|
210
|
+
if node_type == "Emission" and not include_emission(blank_node, product):
|
|
211
|
+
return group
|
|
212
|
+
|
|
208
213
|
is_aggregated_product = node_type == "Product" and term_id == product.get("@id")
|
|
209
214
|
|
|
210
215
|
site_type = cycle.get("site", {}).get("siteType")
|
|
@@ -223,9 +228,9 @@ def _group_cycle_blank_node(cycle: dict, product: dict, product_value: float):
|
|
|
223
228
|
is_aggregated_product=is_aggregated_product,
|
|
224
229
|
)
|
|
225
230
|
|
|
226
|
-
# only primary data can be incomplete, otherwise skip the blank node
|
|
227
231
|
if all(
|
|
228
232
|
[
|
|
233
|
+
# only primary data can be incomplete, otherwise skip the blank node
|
|
229
234
|
complete is False,
|
|
230
235
|
not blank_node_data.get("primary"),
|
|
231
236
|
blank_node_data.get("primaryPercent", 0) <= 0,
|
|
@@ -68,7 +68,7 @@ def _combine_mean_dates(cycles: list):
|
|
|
68
68
|
def _aggregated_weights(weights: dict):
|
|
69
69
|
description = format_weights(weights.values(), include_default_combinations=True)
|
|
70
70
|
return (
|
|
71
|
-
f"This aggregation uses the following weights on sub-systems:
|
|
71
|
+
f"This aggregation uses the following weights on sub-systems: {description}"
|
|
72
72
|
if description
|
|
73
73
|
else ""
|
|
74
74
|
)
|
|
@@ -177,9 +177,7 @@ def _format_results(
|
|
|
177
177
|
"products": non_empty_list(map(_format_aggregate(new_product), products)),
|
|
178
178
|
}
|
|
179
179
|
# aggregate emissions after as it needs inputs and products
|
|
180
|
-
cycle["emissions"] = non_empty_list(
|
|
181
|
-
map(_format_aggregate(new_emission(product)), emissions)
|
|
182
|
-
)
|
|
180
|
+
cycle["emissions"] = non_empty_list(map(_format_aggregate(new_emission), emissions))
|
|
183
181
|
|
|
184
182
|
# set the primary product
|
|
185
183
|
primary_product = find_term_match(cycle.get("products", []), product.get("@id"))
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
from hestia_earth.schema import (
|
|
2
|
+
EmissionMethodTier,
|
|
3
|
+
SchemaType,
|
|
4
|
+
EmissionStatsDefinition,
|
|
5
|
+
)
|
|
6
|
+
from hestia_earth.utils.model import linked_node
|
|
7
|
+
from hestia_earth.utils.lookup_utils import is_in_system_boundary
|
|
8
|
+
from hestia_earth.utils.tools import flatten, non_empty_list
|
|
9
|
+
|
|
10
|
+
from hestia_earth.aggregation.recalculate_cycles import should_recalculate
|
|
11
|
+
from . import _unique_nodes, _set_dict_single
|
|
12
|
+
from .term import METHOD_MODEL
|
|
13
|
+
|
|
14
|
+
_DEFAULT_TIER = EmissionMethodTier.TIER_1.value
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
def include_emission(emission: dict, product: dict):
|
|
18
|
+
return any(
|
|
19
|
+
[
|
|
20
|
+
emission.get("methodTier") != EmissionMethodTier.BACKGROUND.value,
|
|
21
|
+
not should_recalculate(product),
|
|
22
|
+
]
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def new_emission(data: dict):
|
|
27
|
+
term = data.get("term", {})
|
|
28
|
+
# only add emissions included in the System Boundary
|
|
29
|
+
if is_in_system_boundary(term.get("@id")):
|
|
30
|
+
node = {"@type": SchemaType.EMISSION.value}
|
|
31
|
+
node["term"] = linked_node(term)
|
|
32
|
+
value = data.get("value")
|
|
33
|
+
if value is not None:
|
|
34
|
+
node["value"] = [value]
|
|
35
|
+
node["statsDefinition"] = EmissionStatsDefinition.CYCLES.value
|
|
36
|
+
|
|
37
|
+
node["methodTier"] = data.get("methodTier") or _DEFAULT_TIER
|
|
38
|
+
node["methodModel"] = data.get("methodModel") or METHOD_MODEL
|
|
39
|
+
|
|
40
|
+
inputs = data.get("inputs", [])
|
|
41
|
+
# compute list of unique inputs, required for `background` emissions
|
|
42
|
+
if inputs:
|
|
43
|
+
_set_dict_single(
|
|
44
|
+
node,
|
|
45
|
+
"inputs",
|
|
46
|
+
list(map(linked_node, _unique_nodes(inputs))),
|
|
47
|
+
strict=True,
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
if node.get("methodTier") != EmissionMethodTier.NOT_RELEVANT.value:
|
|
51
|
+
_set_dict_single(
|
|
52
|
+
node, "distribution", data.get("distribution"), strict=True
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
_set_dict_single(node, "description", data.get("description"), strict=True)
|
|
56
|
+
return node
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def get_method_tier(emissions: list):
|
|
60
|
+
values = non_empty_list(set(flatten([e.get("methodTier", []) for e in emissions])))
|
|
61
|
+
return values[0] if len(values) == 1 else None
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def get_method_model(emissions: list):
|
|
65
|
+
values = non_empty_list(flatten([e.get("methodModel", []) for e in emissions]))
|
|
66
|
+
values = list({v["@id"]: v for v in values}.values())
|
|
67
|
+
return values[0] if len(values) == 1 else None
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def has_value_without_transformation(blank_node: dict):
|
|
71
|
+
values = blank_node.get("value", [])
|
|
72
|
+
transformations = blank_node.get("transformation", [])
|
|
73
|
+
return (
|
|
74
|
+
not transformations
|
|
75
|
+
or len(transformations) != len(values)
|
|
76
|
+
or any(
|
|
77
|
+
[
|
|
78
|
+
value is not None and transformations[index] is None
|
|
79
|
+
for index, value in enumerate(values)
|
|
80
|
+
]
|
|
81
|
+
)
|
|
82
|
+
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
VERSION = "0.21.17"
|
|
@@ -7,6 +7,7 @@ hestia_earth/aggregation/aggregate_cycles.py
|
|
|
7
7
|
hestia_earth/aggregation/log.py
|
|
8
8
|
hestia_earth/aggregation/recalculate_cycles.py
|
|
9
9
|
hestia_earth/aggregation/version.py
|
|
10
|
+
hestia_earth/aggregation/config/Cycle/crop.json
|
|
10
11
|
hestia_earth/aggregation/config/Cycle/processedFood.json
|
|
11
12
|
hestia_earth/aggregation/utils/__init__.py
|
|
12
13
|
hestia_earth/aggregation/utils/aggregate_country_nodes.py
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
from hestia_earth.schema import (
|
|
2
|
-
EmissionMethodTier,
|
|
3
|
-
SchemaType,
|
|
4
|
-
EmissionStatsDefinition,
|
|
5
|
-
TermTermType,
|
|
6
|
-
)
|
|
7
|
-
from hestia_earth.utils.model import linked_node
|
|
8
|
-
from hestia_earth.utils.lookup_utils import is_in_system_boundary
|
|
9
|
-
from hestia_earth.utils.tools import flatten, non_empty_list
|
|
10
|
-
|
|
11
|
-
from . import _unique_nodes, _set_dict_single
|
|
12
|
-
from .term import METHOD_MODEL
|
|
13
|
-
|
|
14
|
-
_DEFAULT_TIER = EmissionMethodTier.TIER_1.value
|
|
15
|
-
_SKIP_BACKGROUND_EMISSIONS = [TermTermType.PROCESSEDFOOD.value]
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
def _include_emission(emission: dict, product: dict):
|
|
19
|
-
return any(
|
|
20
|
-
[
|
|
21
|
-
emission.get("methodTier") != EmissionMethodTier.BACKGROUND.value,
|
|
22
|
-
product.get("termType") not in _SKIP_BACKGROUND_EMISSIONS,
|
|
23
|
-
]
|
|
24
|
-
)
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
def new_emission(product: dict):
|
|
28
|
-
def emission(data: dict):
|
|
29
|
-
term = data.get("term", {})
|
|
30
|
-
# only add emissions included in the System Boundary
|
|
31
|
-
if is_in_system_boundary(term.get("@id")):
|
|
32
|
-
node = {"@type": SchemaType.EMISSION.value}
|
|
33
|
-
node["term"] = linked_node(term)
|
|
34
|
-
value = data.get("value")
|
|
35
|
-
if value is not None:
|
|
36
|
-
node["value"] = [value]
|
|
37
|
-
node["statsDefinition"] = EmissionStatsDefinition.CYCLES.value
|
|
38
|
-
|
|
39
|
-
node["methodTier"] = data.get("methodTier") or _DEFAULT_TIER
|
|
40
|
-
node["methodModel"] = data.get("methodModel") or METHOD_MODEL
|
|
41
|
-
|
|
42
|
-
inputs = data.get("inputs", [])
|
|
43
|
-
# compute list of unique inputs, required for `background` emissions
|
|
44
|
-
if inputs:
|
|
45
|
-
_set_dict_single(
|
|
46
|
-
node,
|
|
47
|
-
"inputs",
|
|
48
|
-
list(map(linked_node, _unique_nodes(inputs))),
|
|
49
|
-
strict=True,
|
|
50
|
-
)
|
|
51
|
-
|
|
52
|
-
if node.get("methodTier") != EmissionMethodTier.NOT_RELEVANT.value:
|
|
53
|
-
_set_dict_single(
|
|
54
|
-
node, "distribution", data.get("distribution"), strict=True
|
|
55
|
-
)
|
|
56
|
-
|
|
57
|
-
_set_dict_single(node, "description", data.get("description"), strict=True)
|
|
58
|
-
return node if _include_emission(node, product) else None
|
|
59
|
-
|
|
60
|
-
return emission
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
def get_method_tier(emissions: list):
|
|
64
|
-
values = non_empty_list(set(flatten([e.get("methodTier", []) for e in emissions])))
|
|
65
|
-
return values[0] if len(values) == 1 else None
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
def get_method_model(emissions: list):
|
|
69
|
-
values = non_empty_list(flatten([e.get("methodModel", []) for e in emissions]))
|
|
70
|
-
values = list({v["@id"]: v for v in values}.values())
|
|
71
|
-
return values[0] if len(values) == 1 else None
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
def has_value_without_transformation(blank_node: dict):
|
|
75
|
-
values = blank_node.get("value", [])
|
|
76
|
-
transformations = blank_node.get("transformation", [])
|
|
77
|
-
return (
|
|
78
|
-
not transformations
|
|
79
|
-
or len(transformations) != len(values)
|
|
80
|
-
or any(
|
|
81
|
-
[
|
|
82
|
-
value is not None and transformations[index] is None
|
|
83
|
-
for index, value in enumerate(values)
|
|
84
|
-
]
|
|
85
|
-
)
|
|
86
|
-
)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
VERSION = "0.21.16"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{hestia_earth_aggregation-0.21.16 → hestia_earth_aggregation-0.21.17}/tests/test_aggregation.py
RENAMED
|
File without changes
|