hestia-earth-models 0.66.0__py3-none-any.whl → 0.67.0__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.
Files changed (55) hide show
  1. hestia_earth/models/cml2001Baseline/abioticResourceDepletionFossilFuels.py +23 -54
  2. hestia_earth/models/cml2001Baseline/resourceUseEnergyDepletionDuringCycle.py +152 -0
  3. hestia_earth/models/cml2001Baseline/resourceUseEnergyDepletionInputsProduction.py +40 -0
  4. hestia_earth/models/cml2001Baseline/resourceUseMineralsAndMetalsDuringCycle.py +80 -0
  5. hestia_earth/models/cml2001Baseline/resourceUseMineralsAndMetalsInputsProduction.py +40 -0
  6. hestia_earth/models/config/ImpactAssessment.json +1869 -1846
  7. hestia_earth/models/cycle/input/hestiaAggregatedData.py +13 -10
  8. hestia_earth/models/{environmentalFootprintV3 → environmentalFootprintV3_1}/__init__.py +4 -3
  9. hestia_earth/models/environmentalFootprintV3_1/marineEutrophicationPotential.py +36 -0
  10. hestia_earth/models/environmentalFootprintV3_1/scarcityWeightedWaterUse.py +40 -0
  11. hestia_earth/models/impact_assessment/product/value.py +1 -1
  12. hestia_earth/models/ipcc2019/aboveGroundBiomass.py +1 -1
  13. hestia_earth/models/ipcc2019/belowGroundBiomass.py +1 -1
  14. hestia_earth/models/ipcc2019/co2ToAirCarbonStockChange_utils.py +2 -1
  15. hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_1_utils.py +2 -1
  16. hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_2_utils.py +2 -1
  17. hestia_earth/models/mocking/search-results.json +874 -874
  18. hestia_earth/models/site/management.py +2 -2
  19. hestia_earth/models/utils/__init__.py +6 -0
  20. hestia_earth/models/utils/aggregated.py +13 -10
  21. hestia_earth/models/utils/array_builders.py +4 -3
  22. hestia_earth/models/utils/blank_node.py +14 -10
  23. hestia_earth/models/utils/lookup.py +3 -1
  24. hestia_earth/models/utils/property.py +5 -2
  25. hestia_earth/models/version.py +1 -1
  26. hestia_earth/orchestrator/log.py +11 -0
  27. hestia_earth/orchestrator/models/__init__.py +8 -3
  28. {hestia_earth_models-0.66.0.dist-info → hestia_earth_models-0.67.0.dist-info}/METADATA +1 -1
  29. {hestia_earth_models-0.66.0.dist-info → hestia_earth_models-0.67.0.dist-info}/RECORD +55 -43
  30. tests/models/cml2001Baseline/test_abioticResourceDepletionFossilFuels.py +51 -87
  31. tests/models/cml2001Baseline/test_resourceUseEnergyDepletionDuringCycle.py +103 -0
  32. tests/models/cml2001Baseline/test_resourceUseEnergyDepletionInputsProduction.py +23 -0
  33. tests/models/cml2001Baseline/test_resourceUseMineralsAndMetalsDuringCycle.py +58 -0
  34. tests/models/cml2001Baseline/test_resourceUseMineralsAndMetalsInputsProduction.py +23 -0
  35. tests/models/{environmentalFootprintV3 → environmentalFootprintV3_1}/test_environmentalFootprintSingleOverallScore.py +5 -4
  36. tests/models/{environmentalFootprintV3 → environmentalFootprintV3_1}/test_freshwaterEcotoxicityPotentialCtue.py +6 -5
  37. tests/models/environmentalFootprintV3_1/test_marineEutrophicationPotential.py +27 -0
  38. tests/models/environmentalFootprintV3_1/test_scarcityWeightedWaterUse.py +32 -0
  39. tests/models/{environmentalFootprintV3 → environmentalFootprintV3_1}/test_soilQualityIndexLandOccupation.py +4 -3
  40. tests/models/{environmentalFootprintV3 → environmentalFootprintV3_1}/test_soilQualityIndexLandTransformation.py +4 -3
  41. tests/models/{environmentalFootprintV3 → environmentalFootprintV3_1}/test_soilQualityIndexTotalLandUseEffects.py +4 -4
  42. tests/models/impact_assessment/test_emissions.py +0 -1
  43. tests/models/test_config.py +3 -3
  44. tests/models/test_ecoinventV3.py +0 -1
  45. tests/models/utils/test_array_builders.py +2 -2
  46. /hestia_earth/models/{environmentalFootprintV3 → environmentalFootprintV3_1}/environmentalFootprintSingleOverallScore.py +0 -0
  47. /hestia_earth/models/{environmentalFootprintV3 → environmentalFootprintV3_1}/freshwaterEcotoxicityPotentialCtue.py +0 -0
  48. /hestia_earth/models/{environmentalFootprintV3 → environmentalFootprintV3_1}/soilQualityIndexLandOccupation.py +0 -0
  49. /hestia_earth/models/{environmentalFootprintV3 → environmentalFootprintV3_1}/soilQualityIndexLandTransformation.py +0 -0
  50. /hestia_earth/models/{environmentalFootprintV3 → environmentalFootprintV3_1}/soilQualityIndexTotalLandUseEffects.py +0 -0
  51. /hestia_earth/models/{environmentalFootprintV3 → environmentalFootprintV3_1}/utils.py +0 -0
  52. {hestia_earth_models-0.66.0.dist-info → hestia_earth_models-0.67.0.dist-info}/LICENSE +0 -0
  53. {hestia_earth_models-0.66.0.dist-info → hestia_earth_models-0.67.0.dist-info}/WHEEL +0 -0
  54. {hestia_earth_models-0.66.0.dist-info → hestia_earth_models-0.67.0.dist-info}/top_level.txt +0 -0
  55. /tests/models/{environmentalFootprintV3 → environmentalFootprintV3_1}/__init__.py +0 -0
@@ -10,23 +10,18 @@ are converted into MJ.
10
10
 
11
11
  Source : [Life Cycle Assessment & the EF methods - Comprehensive coverage of impacts](https://green-business.ec.europa.eu/environmental-footprint-methods/life-cycle-assessment-ef-methods_en)
12
12
 
13
- The model accepts any non-renewable energy term that can be expressed in, or converted to, MegaJoules.
13
+ The model accepts any non-renewable energy term in MegaJoules, or that has been converted to MegaJoules.
14
14
 
15
15
  Source: [JRC Technical reports Suggestions for updating the Product Environmental Footprint (PEF) method](https://eplca.jrc.ec.europa.eu/permalink/PEF_method.pdf#%5B%7B%22num%22%3A80%2C%22gen%22%3A0%7D%2C%7B%22name%22%3A%22XYZ%22%7D%2C68%2C363%2C0%5D)
16
16
 
17
17
  Source: [Differences between EF model versions](https://eplca.jrc.ec.europa.eu/EFVersioning.html)
18
18
  """ # noqa: E501
19
19
  from itertools import chain
20
- from typing import Optional
21
-
22
- from hestia_earth.schema import TermTermType
23
20
  from hestia_earth.utils.lookup import download_lookup, column_name
24
- from hestia_earth.utils.model import filter_list_term_type
25
21
  from hestia_earth.utils.tools import list_sum, flatten
26
22
 
27
23
  from hestia_earth.models.log import logShouldRun, logRequirements, log_as_table
28
24
  from . import MODEL
29
- from ..utils.blank_node import convert_unit
30
25
  from ..utils.constant import Units
31
26
  from ..utils.indicator import _new_indicator
32
27
  from ..utils.lookup import _node_value
@@ -38,29 +33,13 @@ REQUIREMENTS = {
38
33
  "@type": "Indicator",
39
34
  "term.termType": "resourceUse",
40
35
  "term.@id": ["resourceUseEnergyDepletionInputsProduction", "resourceUseEnergyDepletionDuringCycle"],
36
+ "term.units": "MJ",
41
37
  "value": "> 0",
42
38
  "inputs":
43
39
  {
44
40
  "@type": "Input",
45
41
  "term.name": "non-renewable\" energy terms only,\"",
46
- "term.units": ["kg", "m3", "kWh", "MJ"],
47
- "term.termType": ["fuel", "electricity"],
48
- "optional": {
49
- "defaultProperties": [
50
- {
51
- "@type": "Property",
52
- "value": "",
53
- "term.@id": "energyContentHigherHeatingValue",
54
- "term.units": "MJ / kg"
55
- },
56
- {
57
- "@type": "Property",
58
- "value": "",
59
- "term.@id": "density",
60
- "term.units": "kg / m3"
61
- }
62
- ]
63
- }
42
+ "term.termType": ["fuel", "electricity"]
64
43
  }
65
44
  }
66
45
  ]
@@ -68,8 +47,8 @@ REQUIREMENTS = {
68
47
  }
69
48
 
70
49
  LOOKUPS = {
71
- "fuel": ["energyContentHigherHeatingValue", "density", "abioticResourceDepletionFossilFuelsCml2001Baseline"],
72
- "electricity": ["abioticResourceDepletionFossilFuelsCml2001Baseline"]
50
+ "fuel": ["consideredFossilFuelUnderCml2001Baseline"],
51
+ "electricity": ["consideredFossilFuelUnderCml2001Baseline"]
73
52
  }
74
53
 
75
54
  RETURNS = {
@@ -79,39 +58,31 @@ RETURNS = {
79
58
  }
80
59
  TERM_ID = 'abioticResourceDepletionFossilFuels'
81
60
 
82
- ENERGY_CARRIERS_TERMIDS = REQUIREMENTS['ImpactAssessment']['emissionsResourceUse'][0]['term.@id']
83
-
84
- INPUTS_TYPES_UNITS = {
85
- TermTermType.FUEL.value: [Units.KG.value, Units.M3.value, Units.MJ.value],
86
- TermTermType.ELECTRICITY.value: [Units.KW_H.value, Units.MJ.value]
87
- }
61
+ _ENERGY_CARRIERS_TERMIDS = REQUIREMENTS['ImpactAssessment']['emissionsResourceUse'][0]['term.@id']
88
62
 
89
63
 
90
- def download_all_non_renewable_terms(lookup_file_name: str) -> list:
64
+ def get_all_non_renewable_terms(lookup_file_name: str, column: str) -> list:
91
65
  """
92
66
  returns all non renewable term ids in lookup files like `electricity.csv` or `fuel.csv`
93
67
  """
94
68
  lookup = download_lookup(lookup_file_name)
95
- results = lookup[
96
- lookup[column_name("abioticResourceDepletionFossilFuelsCml2001Baseline")] == True # noqa: E712
97
- ]["termid"]
69
+ results = lookup[lookup[column_name(column)] == True]["termid"] # noqa: E712
98
70
  return list(map(str, results))
99
71
 
100
72
 
101
73
  def _valid_resource_indicator(resource: dict) -> bool:
102
- return len(resource.get('inputs', [])) == 1 and \
103
- isinstance(_node_value(resource), (int, float)) and \
104
- _node_value(resource) > 0
74
+ return (
75
+ len(resource.get('inputs', [])) == 1 and
76
+ isinstance(_node_value(resource), (int, float)) and
77
+ _node_value(resource) > 0 and
78
+ resource.get("term", {}).get("units", "") == Units.MJ.value
79
+ )
105
80
 
106
81
 
107
82
  def _valid_input(input: dict) -> bool:
108
83
  return input.get("@id") in list(chain.from_iterable([
109
- download_all_non_renewable_terms(f"{termType}.csv") for termType in LOOKUPS.keys()
110
- ])) and input.get("units", "") in INPUTS_TYPES_UNITS.get(input.get("termType", ""))
111
-
112
-
113
- def _get_value_in_mj(input: dict, indicator: dict) -> Optional[float]:
114
- return convert_unit(input, dest_unit=Units.MJ, node_value=_node_value(indicator)) if _valid_input(input) else None
84
+ get_all_non_renewable_terms(f"{termType}.csv", columns[0]) for termType, columns in LOOKUPS.items()
85
+ ]))
115
86
 
116
87
 
117
88
  def _indicator(value: float):
@@ -126,9 +97,9 @@ def _run(energy_resources_in_mj: list):
126
97
 
127
98
  def _should_run(impact_assessment: dict) -> tuple[bool, list]:
128
99
  emissions_resource_use = [
129
- resource for resource in
130
- filter_list_term_type(impact_assessment.get('emissionsResourceUse', []), TermTermType.RESOURCEUSE) if
131
- resource.get('term', {}).get('@id', '') in ENERGY_CARRIERS_TERMIDS]
100
+ resource for resource in impact_assessment.get('emissionsResourceUse', [])
101
+ if resource.get('term', {}).get('@id') in _ENERGY_CARRIERS_TERMIDS
102
+ ]
132
103
 
133
104
  has_resource_use_entries = bool(emissions_resource_use)
134
105
 
@@ -140,11 +111,8 @@ def _should_run(impact_assessment: dict) -> tuple[bool, list]:
140
111
  "input-term-type": input.get('termType'),
141
112
  "indicator-term-id": resource_indicator['term']['@id'],
142
113
  "indicator-is-valid": _valid_resource_indicator(resource_indicator),
143
- "input": input,
144
114
  "indicator-input-is-valid": _valid_input(input),
145
- "value": _node_value(resource_indicator),
146
- "input-unit": input.get('units'),
147
- "value-in-MJ": _get_value_in_mj(input, resource_indicator)
115
+ "value-in-MJ": _node_value(resource_indicator) if _valid_input(input) else None,
148
116
  } for input in resource_indicator['inputs'] or [{}]]
149
117
  for resource_indicator in emissions_resource_use
150
118
  ]
@@ -157,8 +125,9 @@ def _should_run(impact_assessment: dict) -> tuple[bool, list]:
157
125
 
158
126
  energy_resources_in_mj = [energy_input['value-in-MJ'] for energy_input in resource_uses_unpacked]
159
127
  valid_energy_resources_in_mj = [value for value in energy_resources_in_mj if value is not None]
160
- all_inputs_have_valid_mj_value = all([energy is not None for energy in energy_resources_in_mj]
161
- ) and bool(energy_resources_in_mj)
128
+ all_inputs_have_valid_mj_value = all(
129
+ [energy is not None for energy in energy_resources_in_mj] + [bool(energy_resources_in_mj)]
130
+ )
162
131
 
163
132
  logRequirements(impact_assessment, model=MODEL, term=TERM_ID,
164
133
  has_resource_use_entries=has_resource_use_entries,
@@ -0,0 +1,152 @@
1
+ """
2
+ This model converts all "energy" terms found in a `Cycle > Inputs` to `MJ` using optional
3
+ `energyContentHigherHeatingValue` and `density` properties or the term's "defaultProperties",
4
+ aggregates them, and places them inside a 'resourceUseEnergyDepletionDuringCycle' indicator per aggregated input id.
5
+ """
6
+ from collections import defaultdict
7
+ from itertools import groupby
8
+ from typing import Tuple, Optional
9
+
10
+ from hestia_earth.schema import TermTermType
11
+ from hestia_earth.utils.model import filter_list_term_type
12
+ from hestia_earth.utils.tools import list_sum
13
+
14
+ from hestia_earth.models.log import logRequirements, logShouldRun, log_as_table
15
+ from hestia_earth.models.utils import Units
16
+ from hestia_earth.models.utils.blank_node import convert_unit
17
+ from hestia_earth.models.utils.indicator import _new_indicator
18
+ from . import MODEL
19
+ from ..utils.lookup import _node_value
20
+
21
+ REQUIREMENTS = {
22
+ "Cycle": {
23
+ "inputs": [
24
+ {
25
+ "@type": "Input",
26
+ "term.units": ["kg", "m3", "kWh", "MJ"],
27
+ "term.termType": ["fuel", "electricity"],
28
+ "value": ">0",
29
+ "optional": {
30
+ "properties": [
31
+ {
32
+ "@type": "Property",
33
+ "value": "",
34
+ "term.@id": "energyContentHigherHeatingValue",
35
+ "term.units": "MJ / kg"
36
+ },
37
+ {
38
+ "@type": "Property",
39
+ "value": "",
40
+ "term.@id": "density",
41
+ "term.units": "kg / m3"
42
+ }
43
+ ]
44
+ }
45
+ }
46
+ ]
47
+ }
48
+ }
49
+
50
+ RETURNS = {
51
+ "Indicator": [
52
+ {
53
+ "value": "",
54
+ "inputs": ""
55
+ }
56
+ ]
57
+ }
58
+
59
+ LOOKUPS = {
60
+ "fuel": ["energyContentHigherHeatingValue", "density"]
61
+ }
62
+
63
+ TERM_ID = 'resourceUseEnergyDepletionDuringCycle'
64
+
65
+ INPUTS_TYPES_UNITS = {
66
+ TermTermType.FUEL.value: [Units.KG.value, Units.M3.value, Units.MJ.value],
67
+ TermTermType.ELECTRICITY.value: [Units.KW_H.value, Units.MJ.value]
68
+ }
69
+
70
+
71
+ def _indicator(values: list[float], cycle_input: dict):
72
+ indicator = _new_indicator(TERM_ID, MODEL)
73
+ indicator['value'] = list_sum(values)
74
+ indicator['inputs'] = [cycle_input | {"units": "MJ"}]
75
+ return indicator
76
+
77
+
78
+ def _run(grouped_energy_terms: dict):
79
+ indicators = [_indicator(values=[input['value-in-MJ'] for input in energy_term_group_vals],
80
+ cycle_input=energy_term_group_vals[0]['input']['term'])
81
+ for energy_term_group_vals in grouped_energy_terms.values()]
82
+ return indicators
83
+
84
+
85
+ def _valid_input(input: dict) -> bool:
86
+ return (isinstance(_node_value(input), (int, float))
87
+ and _node_value(input) > 0
88
+ and input.get("term", {}).get("units", "") in INPUTS_TYPES_UNITS.get(input.get("term", {}).get("termType")))
89
+
90
+
91
+ def _get_value_in_mj(input: dict) -> Optional[float]:
92
+ return convert_unit(input, dest_unit=Units.MJ, node_value=_node_value(input)) if _valid_input(input) else None
93
+
94
+
95
+ def _should_run(cycle: dict) -> Tuple[bool, dict]:
96
+ energy_input_terms = filter_list_term_type(cycle.get('inputs', []), [TermTermType.FUEL, TermTermType.ELECTRICITY])
97
+
98
+ has_energy_terms = bool(energy_input_terms)
99
+
100
+ energy_input_terms_unpacked = [
101
+ {
102
+ "id": input.get('term', {}).get('@id'),
103
+ "termType": input.get('term', {}).get('termType'),
104
+ "input-is-valid": _valid_input(input),
105
+ "value": _node_value(input),
106
+ "input": input,
107
+ "units": input.get('term', {}).get('units'),
108
+ "value-in-MJ": _get_value_in_mj(input)
109
+ }
110
+ for input in energy_input_terms
111
+ ]
112
+
113
+ has_valid_input_requirements = all([energy_input['input-is-valid'] for energy_input in energy_input_terms_unpacked])
114
+
115
+ energy_input_terms_valid = [e for e in energy_input_terms_unpacked if e["value-in-MJ"] is not None]
116
+
117
+ energy_input_terms_in_mj = [energy_input['value-in-MJ'] for energy_input in energy_input_terms_unpacked]
118
+ all_inputs_have_valid_mj_value = all([mj_value is not None for mj_value in energy_input_terms_in_mj]
119
+ ) and bool(energy_input_terms_in_mj)
120
+
121
+ grouped_energy_terms = defaultdict(list)
122
+ for k, v in groupby(energy_input_terms_valid, key=lambda x: x.get('id')):
123
+ grouped_energy_terms[k].extend(list(v))
124
+
125
+ logs = [
126
+ {
127
+ 'id': input.get('@id'),
128
+ 'units': input.get('units'),
129
+ 'termType': input.get('termType'),
130
+ 'value': input.get('value'),
131
+ 'value-in-MJ': input.get('value-in-MJ'),
132
+ 'properties': " ".join([
133
+ f"{p.get('term', {}).get('@id')}= {p.get('value')} ({p.get('term', {}).get('units')})"
134
+ for p in input.get('properties', [])
135
+ ])
136
+ } for input in energy_input_terms_unpacked
137
+ ]
138
+ logRequirements(cycle, model=MODEL, term=TERM_ID,
139
+ has_energy_terms=has_energy_terms,
140
+ has_valid_input_requirements=has_valid_input_requirements,
141
+ all_inputs_have_valid_mj_value=all_inputs_have_valid_mj_value,
142
+ energy_resources_used=log_as_table(logs))
143
+
144
+ should_run = all([has_valid_input_requirements, all_inputs_have_valid_mj_value])
145
+
146
+ logShouldRun(cycle, MODEL, TERM_ID, should_run)
147
+ return should_run, grouped_energy_terms
148
+
149
+
150
+ def run(cycle: dict):
151
+ should_run, grouped_energy_terms = _should_run(cycle)
152
+ return _run(grouped_energy_terms) if should_run else []
@@ -0,0 +1,40 @@
1
+ from hestia_earth.models.linkedImpactAssessment.utils import run_inputs_production
2
+
3
+ REQUIREMENTS = {
4
+ "ImpactAssessment": {
5
+ "product": {"@type": "Term"},
6
+ "cycle": {
7
+ "@type": "Cycle",
8
+ "products": [{
9
+ "@type": "Product",
10
+ "primary": "True",
11
+ "value": "> 0",
12
+ "economicValueShare": "> 0"
13
+ }],
14
+ "inputs": [{
15
+ "@type": "Input",
16
+ "impactAssessment": {
17
+ "@type": "ImpactAssessment",
18
+ "emissionsResourceUse": [{
19
+ "@type": "Indicator",
20
+ "term.@id": [
21
+ "resourceUseEnergyDepletionDuringCycle",
22
+ "resourceUseEnergyDepletionInputsProduction"
23
+ ],
24
+ "value": "> 0"
25
+ }]
26
+ }
27
+ }]
28
+ }
29
+ }
30
+ }
31
+ RETURNS = {
32
+ "Indicator": [{
33
+ "value": "",
34
+ "inputs": "units in MJ"
35
+ }]
36
+ }
37
+ TERM_ID = 'resourceUseEnergyDepletionInputsProduction'
38
+
39
+
40
+ def run(impact_assessment: dict): return run_inputs_production(impact_assessment, TERM_ID)
@@ -0,0 +1,80 @@
1
+ """
2
+ This model converts most abiotic resources terms found in a `Cycle > Inputs`, aggregates them,
3
+ and converts them to one indicator per input.
4
+ """
5
+ from collections import defaultdict
6
+ from itertools import groupby
7
+ from typing import Tuple
8
+ from hestia_earth.schema import TermTermType
9
+ from hestia_earth.utils.model import filter_list_term_type
10
+ from hestia_earth.utils.tools import list_sum
11
+
12
+ from hestia_earth.models.log import logRequirements, logShouldRun
13
+ from hestia_earth.models.utils import _filter_list_term_unit, Units
14
+ from hestia_earth.models.utils.blank_node import _sum_nodes_value
15
+ from hestia_earth.models.utils.indicator import _new_indicator
16
+ from . import MODEL
17
+
18
+ REQUIREMENTS = {
19
+ "Cycle": {
20
+ "inputs": [
21
+ {
22
+ "@type": "Input",
23
+ "term.units": "kg",
24
+ "term.termType": ["material", "soilAmendment", "otherInorganicChemical"]}
25
+ ]
26
+ }
27
+ }
28
+
29
+ RETURNS = {
30
+ "Indicator": [{
31
+ "value": "",
32
+ "inputs": ""
33
+ }]
34
+ }
35
+ TERM_ID = 'resourceUseMineralsAndMetalsDuringCycle'
36
+
37
+ authorised_term_types = [TermTermType.MATERIAL, TermTermType.SOILAMENDMENT, TermTermType.OTHERINORGANICCHEMICAL]
38
+
39
+
40
+ def _indicator(value: list[float], cycle_input: dict):
41
+ indicator = _new_indicator(TERM_ID, MODEL)
42
+ indicator['value'] = list_sum(value)
43
+ indicator['inputs'] = [cycle_input]
44
+ return indicator
45
+
46
+
47
+ def _run(grouped_abiotic_terms: dict):
48
+ indicators = [
49
+ _indicator(value=_sum_nodes_value(abiotic_term_group_vals),
50
+ cycle_input=abiotic_term_group_vals[0]['term'])
51
+ for abiotic_term_group_vals in grouped_abiotic_terms.values()
52
+ ]
53
+ return indicators
54
+
55
+
56
+ def _should_run(cycle: dict) -> Tuple[bool, dict]:
57
+ abiotic_terms = filter_list_term_type(cycle.get('inputs', []), authorised_term_types)
58
+ abiotic_terms_valid_units = _filter_list_term_unit(abiotic_terms, Units.KG)
59
+
60
+ has_abiotic_terms = bool(abiotic_terms)
61
+ has_valid_terms = bool(abiotic_terms_valid_units)
62
+
63
+ grouped_abiotic_terms = defaultdict(list)
64
+ for k, v in groupby(abiotic_terms_valid_units,
65
+ key=lambda x: (x['term']['@id'], x['term']['units'], x['term']['termType'])):
66
+ grouped_abiotic_terms[k].extend(list(v))
67
+
68
+ logRequirements(cycle, model=MODEL, term=TERM_ID,
69
+ has_abiotic_terms=has_abiotic_terms,
70
+ has_valid_terms=has_valid_terms,
71
+ )
72
+
73
+ should_run = all([has_valid_terms])
74
+ logShouldRun(cycle, MODEL, TERM_ID, should_run)
75
+ return should_run, grouped_abiotic_terms
76
+
77
+
78
+ def run(cycle: dict):
79
+ should_run, grouped_abiotic_terms = _should_run(cycle)
80
+ return _run(grouped_abiotic_terms) if should_run else []
@@ -0,0 +1,40 @@
1
+ from hestia_earth.models.linkedImpactAssessment.utils import run_inputs_production
2
+
3
+ REQUIREMENTS = {
4
+ "ImpactAssessment": {
5
+ "product": {"@type": "Term"},
6
+ "cycle": {
7
+ "@type": "Cycle",
8
+ "products": [{
9
+ "@type": "Product",
10
+ "primary": "True",
11
+ "value": "> 0",
12
+ "economicValueShare": "> 0"
13
+ }],
14
+ "inputs": [{
15
+ "@type": "Input",
16
+ "impactAssessment": {
17
+ "@type": "ImpactAssessment",
18
+ "emissionsResourceUse": [{
19
+ "@type": "Indicator",
20
+ "term.@id": [
21
+ "resourceUseMineralsAndMetalsDuringCycle",
22
+ "resourceUseMineralsAndMetalsInputsProduction"
23
+ ],
24
+ "value": "> 0"
25
+ }]
26
+ }
27
+ }]
28
+ }
29
+ }
30
+ }
31
+ RETURNS = {
32
+ "Indicator": [{
33
+ "value": "",
34
+ "inputs": ""
35
+ }]
36
+ }
37
+ TERM_ID = 'resourceUseMineralsAndMetalsInputsProduction'
38
+
39
+
40
+ def run(impact_assessment: dict): return run_inputs_production(impact_assessment, TERM_ID)