hestia-earth-models 0.64.2__py3-none-any.whl → 0.64.4__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.

Files changed (57) hide show
  1. hestia_earth/models/agribalyse2016/machineryInfrastructureDepreciatedAmountPerCycle.py +2 -2
  2. hestia_earth/models/cycle/animal/input/hestiaAggregatedData.py +5 -2
  3. hestia_earth/models/cycle/animal/input/properties.py +2 -1
  4. hestia_earth/models/cycle/animal/milkYield.py +2 -1
  5. hestia_earth/models/cycle/concentrateFeed.py +8 -8
  6. hestia_earth/models/cycle/cycleDuration.py +4 -5
  7. hestia_earth/models/cycle/siteDuration.py +15 -5
  8. hestia_earth/models/cycle/startDateDefinition.py +3 -4
  9. hestia_earth/models/cycle/stockingDensityAnimalHousingAverage.py +52 -0
  10. hestia_earth/models/fantkeEtAl2016/__init__.py +13 -0
  11. hestia_earth/models/fantkeEtAl2016/damageToHumanHealthParticulateMatterFormation.py +49 -0
  12. hestia_earth/models/frischknechtEtAl2000/__init__.py +13 -0
  13. hestia_earth/models/frischknechtEtAl2000/ionisingRadiationKbqU235Eq.py +90 -0
  14. hestia_earth/models/ipcc2019/aboveGroundBiomass.py +762 -0
  15. hestia_earth/models/ipcc2019/aboveGroundBiomass_utils.py +180 -0
  16. hestia_earth/models/ipcc2019/animal/liveweightGain.py +89 -0
  17. hestia_earth/models/ipcc2019/animal/liveweightPerHead.py +89 -0
  18. hestia_earth/models/ipcc2019/animal/pastureGrass.py +51 -42
  19. hestia_earth/models/ipcc2019/animal/utils.py +20 -0
  20. hestia_earth/models/ipcc2019/animal/weightAtMaturity.py +15 -19
  21. hestia_earth/models/ipcc2019/ch4ToAirExcreta.py +2 -2
  22. hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_1_utils.py +37 -50
  23. hestia_earth/models/ipcc2019/organicCarbonPerHa_utils.py +0 -19
  24. hestia_earth/models/ipcc2019/pastureGrass.py +44 -31
  25. hestia_earth/models/ipcc2019/pastureGrass_utils.py +38 -22
  26. hestia_earth/models/mocking/search-results.json +228 -228
  27. hestia_earth/models/poschEtAl2008/terrestrialEutrophicationPotentialAccumulatedExceedance.py +40 -0
  28. hestia_earth/models/site/soilMeasurement.py +2 -2
  29. hestia_earth/models/utils/blank_node.py +20 -1
  30. hestia_earth/models/utils/crop.py +4 -0
  31. hestia_earth/models/utils/ecoClimateZone.py +99 -0
  32. hestia_earth/models/utils/emission.py +6 -2
  33. hestia_earth/models/utils/impact_assessment.py +10 -5
  34. hestia_earth/models/utils/lookup.py +5 -3
  35. hestia_earth/models/utils/productivity.py +1 -1
  36. hestia_earth/models/utils/property.py +2 -2
  37. hestia_earth/models/version.py +1 -1
  38. {hestia_earth_models-0.64.2.dist-info → hestia_earth_models-0.64.4.dist-info}/METADATA +1 -1
  39. {hestia_earth_models-0.64.2.dist-info → hestia_earth_models-0.64.4.dist-info}/RECORD +57 -35
  40. tests/models/cycle/test_siteDuration.py +22 -0
  41. tests/models/cycle/test_stockingDensityAnimalHousingAverage.py +42 -0
  42. tests/models/fantkeEtAl2016/__init__.py +0 -0
  43. tests/models/fantkeEtAl2016/test_damageToHumanHealthParticulateMatterFormation.py +20 -0
  44. tests/models/frischknechtEtAl2000/__init__.py +0 -0
  45. tests/models/frischknechtEtAl2000/test_ionisingRadiationKbqU235Eq.py +70 -0
  46. tests/models/ipcc2019/animal/test_liveweightGain.py +20 -0
  47. tests/models/ipcc2019/animal/test_liveweightPerHead.py +20 -0
  48. tests/models/ipcc2019/animal/test_pastureGrass.py +1 -1
  49. tests/models/ipcc2019/test_aboveGroundBiomass.py +182 -0
  50. tests/models/ipcc2019/test_aboveGroundBiomass_utils.py +92 -0
  51. tests/models/ipcc2019/test_organicCarbonPerHa_tier_1_utils.py +3 -2
  52. tests/models/ipcc2019/test_pastureGrass.py +2 -2
  53. tests/models/poschEtAl2008/test_terrestrialEutrophicationPotentialAccumulatedExceedance.py +44 -0
  54. tests/models/utils/test_ecoClimateZone.py +152 -0
  55. {hestia_earth_models-0.64.2.dist-info → hestia_earth_models-0.64.4.dist-info}/LICENSE +0 -0
  56. {hestia_earth_models-0.64.2.dist-info → hestia_earth_models-0.64.4.dist-info}/WHEEL +0 -0
  57. {hestia_earth_models-0.64.2.dist-info → hestia_earth_models-0.64.4.dist-info}/top_level.txt +0 -0
@@ -12,7 +12,7 @@ of less than 0.8.
12
12
  from hestia_earth.utils.tools import list_sum, flatten
13
13
 
14
14
  from hestia_earth.models.log import logRequirements, logShouldRun, debugValues, log_as_table
15
- from hestia_earth.models.utils.productivity import _get_productivity, PRODUCTIVITY
15
+ from hestia_earth.models.utils.productivity import get_productivity, PRODUCTIVITY
16
16
  from hestia_earth.models.utils.input import _new_input
17
17
  from hestia_earth.models.utils.completeness import _is_term_type_incomplete
18
18
  from hestia_earth.models.utils.term import get_liquid_fuel_terms
@@ -58,7 +58,7 @@ def _get_input_value_from_term(inputs: list, term_id: str):
58
58
 
59
59
  def get_value(country: dict, cycle: dict):
60
60
  liquid_fuels = get_liquid_fuel_terms()
61
- productivity_key = _get_productivity(country)
61
+ productivity_key = get_productivity(country)
62
62
  machinery_usage = 11.5 if productivity_key == PRODUCTIVITY.HIGH else 23
63
63
  values = [(term_id, _get_input_value_from_term(cycle.get('inputs', []), term_id)) for term_id in liquid_fuels]
64
64
  value_logs = log_as_table([{'id': term_id, 'value': value} for term_id, value in values])
@@ -48,9 +48,12 @@ def _run_animal_input(cycle: dict, input: dict):
48
48
 
49
49
 
50
50
  def _run_animal(cycle: dict, animal: dict):
51
- inputs = [input for input in animal.get('inputs', []) if should_link_input_to_impact(cycle)(input)]
52
51
  return animal | {
53
- 'inputs': [_run_animal_input(cycle, input) for input in inputs]
52
+ 'inputs': [
53
+ (
54
+ _run_animal_input(cycle, input) if should_link_input_to_impact(cycle)(input) else input
55
+ ) for input in animal.get('inputs', [])
56
+ ]
54
57
  }
55
58
 
56
59
 
@@ -12,6 +12,7 @@ from hestia_earth.utils.model import find_term_match
12
12
 
13
13
  from hestia_earth.models.log import logShouldRun
14
14
  from hestia_earth.models.utils import _load_calculated_node
15
+ from hestia_earth.models.utils.blank_node import merge_blank_nodes
15
16
  from hestia_earth.models.utils.feedipedia import rescale_properties_from_dryMatter
16
17
  from ...utils import should_run_properties_value, average_blank_node_properties_value
17
18
  from ... import MODEL
@@ -61,7 +62,7 @@ def _run_input_by_impactAssessment(cycle: dict):
61
62
  new_properties = [p for p in properties if not find_term_match(all_properties, p.get('term', {}).get('@id'))]
62
63
  for prop in new_properties:
63
64
  logShouldRun(cycle, MODEL, term_id, True, property=prop.get('term', {}).get('@id'))
64
- return {**input, 'properties': all_properties + new_properties} if new_properties else input
65
+ return {**input, 'properties': merge_blank_nodes(all_properties, new_properties)} if new_properties else input
65
66
  return exec
66
67
 
67
68
 
@@ -10,6 +10,7 @@ from hestia_earth.utils.model import filter_list_term_type
10
10
  from hestia_earth.utils.tools import non_empty_list, safe_parse_float
11
11
 
12
12
  from hestia_earth.models.log import logShouldRun, logRequirements, log_blank_nodes_id
13
+ from hestia_earth.models.utils.blank_node import merge_blank_nodes
13
14
  from hestia_earth.models.utils.term import get_lookup_value
14
15
  from hestia_earth.models.utils.practice import _new_practice
15
16
  from .. import MODEL
@@ -68,7 +69,7 @@ def _run(cycle: dict, animal: dict):
68
69
 
69
70
  return {
70
71
  **animal,
71
- 'practices': animal.get('practices', []) + practices
72
+ 'practices': merge_blank_nodes(animal.get('practices', []), practices)
72
73
  } if practices else None
73
74
 
74
75
 
@@ -16,7 +16,7 @@ from . import MODEL
16
16
  REQUIREMENTS = {
17
17
  "Cycle": {
18
18
  "inputs": [{
19
- "@type": "Practice", "value": "", "term.termType": ["crop", "forage", "processedFood", "animalProduct"]
19
+ "@type": "Input", "value": "", "term.termType": ["crop", "forage", "processedFood", "animalProduct"]
20
20
  }],
21
21
  "products": [
22
22
  {
@@ -58,17 +58,17 @@ def _property(term_id: str, value: float):
58
58
  def _min_ratio(term_id: str):
59
59
  value = get_property_lookup_value(MODEL, term_id, LOOKUPS['property'])
60
60
  # value is a Numpy bool so use negation
61
- return 1 if not value else 0.8
61
+ return 0.8 if not value else 1
62
62
 
63
63
 
64
64
  def _weighted_value(values: list):
65
- total_weight = sum(weight for _v, weight in values)
66
- weighted_values = [value * weight for value, weight in values]
65
+ total_weight = sum(input_value for prop_value, input_value in values)
66
+ weighted_values = [prop_value * input_value for prop_value, input_value in values]
67
67
  return sum(weighted_values) / (total_weight if total_weight != 0 else 1)
68
68
 
69
69
 
70
70
  def _calculate_value(cycle: dict, product: dict, inputs: list, property_id: str, values: list):
71
- values = [(prop_value, value) for id, prop_value, value in values if value and prop_value]
71
+ values = [(prop_value, input_value) for id, prop_value, input_value in values if input_value and prop_value]
72
72
  ratio_inputs_with_props = len(values) / len(inputs) if len(inputs) and len(values) else 0
73
73
  min_ratio = _min_ratio(property_id)
74
74
 
@@ -88,7 +88,7 @@ def _calculate_value(cycle: dict, product: dict, inputs: list, property_id: str,
88
88
  def _calculate_default_value(cycle: dict, product: dict, inputs: list, property_id: str):
89
89
  values = [(
90
90
  i.get('term', {}).get('@id'),
91
- get_node_property_value(MODEL, i, property_id, term=TERM_ID),
91
+ get_node_property_value(MODEL, i, property_id, handle_percents=False, term=TERM_ID),
92
92
  list_sum(i.get('value', []))
93
93
  ) for i in inputs]
94
94
  return _calculate_value(cycle, product, inputs, property_id, values)
@@ -97,8 +97,8 @@ def _calculate_default_value(cycle: dict, product: dict, inputs: list, property_
97
97
  def _calculate_N_value(cycle: dict, product: dict, inputs: list, property_id: str):
98
98
  values = [(
99
99
  i.get('term', {}).get('@id'),
100
- get_node_property_value(MODEL, i, property_id, term=TERM_ID) or
101
- get_node_property_value(MODEL, i, 'crudeProteinContent', default=0, term=TERM_ID) * 0.16,
100
+ get_node_property_value(MODEL, i, property_id, handle_percents=False, term=TERM_ID) or
101
+ get_node_property_value(MODEL, i, 'crudeProteinContent', default=0, handle_percents=False, term=TERM_ID) * 0.16,
102
102
  list_sum(i.get('value', []))
103
103
  ) for i in inputs]
104
104
  return _calculate_value(cycle, product, inputs, property_id, values)
@@ -11,7 +11,7 @@ from hestia_earth.utils.model import find_term_match, find_primary_product
11
11
  from hestia_earth.utils.date import diff_in_days
12
12
 
13
13
  from hestia_earth.models.log import logRequirements, logShouldRun, debugValues
14
- from hestia_earth.models.utils.crop import get_crop_grouping_fao
14
+ from hestia_earth.models.utils.crop import is_permanent_crop
15
15
  from . import MODEL
16
16
 
17
17
  REQUIREMENTS = {
@@ -63,12 +63,11 @@ def _should_run_by_dates(cycle: dict):
63
63
 
64
64
  def _run_by_crop(cycle: dict):
65
65
  product = find_primary_product(cycle)
66
- grouping = get_crop_grouping_fao(MODEL, MODEL_KEY, product.get('term', {}))
67
- is_permanent_crop = grouping == 'Permanent crops'
66
+ permanent_crop = is_permanent_crop(MODEL, MODEL_KEY, product.get('term', {}))
68
67
  croppingIntensity = find_term_match(cycle.get('practices', []), 'croppingIntensity').get('value', [1])[0]
69
- ratio = 1 if is_permanent_crop else croppingIntensity
68
+ ratio = 1 if permanent_crop else croppingIntensity
70
69
  debugValues(cycle, model=MODEL, key=MODEL_KEY, by='product',
71
- crop_grouping=grouping,
70
+ is_permanent_crop=permanent_crop,
72
71
  croppingIntensity=croppingIntensity,
73
72
  ratio=ratio)
74
73
  return round(DEFAULT_DURATION * ratio, 3)
@@ -4,12 +4,15 @@ Site duration
4
4
  This model calculates the `siteDuration` on the `Cycle` to the same value as `cycleDuration`
5
5
  when only a single `Site` is present.
6
6
 
7
- Note: on `crop` production cycles, the model will only run if `startDateDefinition` = `harvest of previous crop`.
7
+ Note: on `crop` production cycles:
8
+ * For temporary crops, gap fill only when `startDateDefinition` = `harvest of previous crop`.
9
+ * For permanent crops, no restriction applies.
8
10
  """
9
11
  from hestia_earth.schema import TermTermType, CycleStartDateDefinition
10
12
  from hestia_earth.utils.model import find_primary_product
11
13
 
12
14
  from hestia_earth.models.log import logRequirements, logShouldRun
15
+ from hestia_earth.models.utils.crop import is_permanent_crop
13
16
  from . import MODEL
14
17
 
15
18
  REQUIREMENTS = {
@@ -39,20 +42,27 @@ def _run(cycle: dict): return cycle.get('cycleDuration')
39
42
 
40
43
  def _should_run(cycle: dict):
41
44
  cycleDuration = cycle.get('cycleDuration', 0)
42
- has_other_sites = len(cycle.get('otherSites', [])) == 0
45
+ has_single_site = len(cycle.get('otherSites', [])) == 0
43
46
 
44
47
  product = find_primary_product(cycle)
45
- is_primary_crop_product = (product or {}).get('term', {}).get('termType') == TermTermType.CROP.value
48
+ product_term = (product or {}).get('term', {})
49
+ is_primary_crop_product = product_term.get('termType') == TermTermType.CROP.value
50
+ permanent_crop = is_permanent_crop(MODEL, MODEL_KEY, product_term)
46
51
  harvest_previous_crop = CycleStartDateDefinition.HARVEST_OF_PREVIOUS_CROP.value
47
52
  is_harvest_previous_crop = cycle.get('startDateDefinition') == harvest_previous_crop
48
53
 
49
54
  logRequirements(cycle, model=MODEL, key=MODEL_KEY,
50
55
  cycleDuration=cycleDuration,
51
- has_other_sites=has_other_sites,
56
+ has_single_site=has_single_site,
52
57
  is_primary_crop_product=is_primary_crop_product,
58
+ is_permanent_crop=permanent_crop,
53
59
  is_harvest_previous_crop=is_harvest_previous_crop)
54
60
 
55
- should_run = all([cycleDuration > 0, has_other_sites, not is_primary_crop_product or is_harvest_previous_crop])
61
+ should_run = all([
62
+ cycleDuration > 0,
63
+ has_single_site,
64
+ not is_primary_crop_product or permanent_crop or is_harvest_previous_crop
65
+ ])
56
66
  logShouldRun(cycle, MODEL, None, should_run, key=MODEL_KEY)
57
67
  return should_run
58
68
 
@@ -8,7 +8,7 @@ from hestia_earth.schema import TermTermType, CycleStartDateDefinition
8
8
  from hestia_earth.utils.model import find_primary_product
9
9
 
10
10
  from hestia_earth.models.log import logRequirements, logShouldRun
11
- from hestia_earth.models.utils.crop import get_crop_grouping_fao
11
+ from hestia_earth.models.utils.crop import is_permanent_crop
12
12
  from . import MODEL
13
13
 
14
14
  REQUIREMENTS = {
@@ -40,12 +40,11 @@ def _is_last_day_of_month(date: str):
40
40
 
41
41
  def _run(cycle: dict):
42
42
  product = find_primary_product(cycle)
43
- grouping = get_crop_grouping_fao(MODEL, MODEL_KEY, product.get('term', {}))
44
- is_permanent_crop = grouping == 'Permanent crops'
43
+ permanent_crop = is_permanent_crop(MODEL, MODEL_KEY, product.get('term', {}))
45
44
  return (
46
45
  CycleStartDateDefinition.START_OF_YEAR.value if _is_last_day_of_month(cycle.get('endDate'))
47
46
  else CycleStartDateDefinition.ONE_YEAR_PRIOR.value
48
- ) if is_permanent_crop else (
47
+ ) if permanent_crop else (
49
48
  CycleStartDateDefinition.HARVEST_OF_PREVIOUS_CROP.value
50
49
  )
51
50
 
@@ -0,0 +1,52 @@
1
+ from hestia_earth.schema import TermTermType
2
+ from hestia_earth.utils.model import find_primary_product
3
+
4
+ from hestia_earth.models.log import logRequirements, logShouldRun
5
+ from hestia_earth.models.utils.blank_node import get_lookup_value
6
+ from hestia_earth.models.utils.practice import _new_practice
7
+ from . import MODEL
8
+
9
+ REQUIREMENTS = {
10
+ "Cycle": {
11
+ "products": [{
12
+ "@type": "Product",
13
+ "primary": "True",
14
+ "term.termType": "liveAnimal"
15
+ }]
16
+ }
17
+ }
18
+ RETURNS = {
19
+ "Practice": [{
20
+ "value": ""
21
+ }]
22
+ }
23
+ LOOKUPS = {
24
+ "liveAnimal": "stockingDensityAnimalHousing"
25
+ }
26
+ TERM_ID = 'stockingDensityAnimalHousingAverage'
27
+
28
+
29
+ def _practice(value: float):
30
+ practice = _new_practice(TERM_ID)
31
+ practice['value'] = [round(value, 7)]
32
+ return practice
33
+
34
+
35
+ def _should_run(cycle: dict):
36
+ product = find_primary_product(cycle)
37
+ is_live_animal_product = (product or {}).get('term', {}).get('termType') == TermTermType.LIVEANIMAL.value
38
+
39
+ lookup_value = get_lookup_value((product or {}).get('term', {}), LOOKUPS['liveAnimal'])
40
+
41
+ logRequirements(cycle, model=MODEL, term=TERM_ID,
42
+ is_live_animal_product=is_live_animal_product,
43
+ lookup_value=lookup_value)
44
+
45
+ should_run = all([is_live_animal_product > 0, lookup_value is not None])
46
+ logShouldRun(cycle, MODEL, TERM_ID, should_run)
47
+ return should_run, lookup_value
48
+
49
+
50
+ def run(cycle: dict):
51
+ should_run, lookup_value = _should_run(cycle)
52
+ return _practice(lookup_value) if should_run else []
@@ -0,0 +1,13 @@
1
+ from os.path import dirname, abspath
2
+ import sys
3
+ from importlib import import_module
4
+
5
+ from hestia_earth.models.utils.blank_node import run_if_required
6
+
7
+ CURRENT_DIR = dirname(abspath(__file__)) + '/'
8
+ sys.path.append(CURRENT_DIR)
9
+ MODEL = 'fantkeEtAl2016'
10
+ PKG = '.'.join(['hestia_earth', 'models', MODEL])
11
+
12
+
13
+ def run(model: str, data): return run_if_required(MODEL, model, data, import_module(f".{model}", package=PKG))
@@ -0,0 +1,49 @@
1
+ from hestia_earth.utils.lookup import column_name
2
+
3
+ from hestia_earth.models.log import logRequirements, logShouldRun
4
+ from . import MODEL
5
+ from ..utils.impact_assessment import impact_lookup_value
6
+ from ..utils.indicator import _new_indicator
7
+
8
+ REQUIREMENTS = {
9
+ "ImpactAssessment": {
10
+ "emissionsResourceUse": [
11
+ {
12
+ "@type": "Indicator", "value": "", "term.termType": "emission"
13
+ }
14
+ ]
15
+ }
16
+ }
17
+
18
+ TERM_ID = 'damageToHumanHealthParticulateMatterFormation'
19
+
20
+ LOOKUPS = {
21
+ "emission": "damageToHumanHealthParticulateMatterFormationFantkeEtAl2016"
22
+ }
23
+
24
+ RETURNS = {
25
+ "Indicator": {
26
+ "value": ""
27
+ }
28
+ }
29
+
30
+ default_group_key = 'default'
31
+
32
+
33
+ def _indicator(value: float):
34
+ indicator = _new_indicator(TERM_ID, MODEL)
35
+ indicator['value'] = value
36
+ return indicator
37
+
38
+
39
+ def run(impact_assessment: dict):
40
+ value = impact_lookup_value(model=MODEL, term_id=TERM_ID, impact=impact_assessment,
41
+ lookup_col=column_name(LOOKUPS['emission']),
42
+ grouped_key=default_group_key)
43
+ logRequirements(impact_assessment, model=MODEL, term=TERM_ID,
44
+ value=value)
45
+
46
+ should_run = all([value is not None])
47
+ logShouldRun(impact_assessment, MODEL, TERM_ID, should_run)
48
+
49
+ return _indicator(value) if should_run else None
@@ -0,0 +1,13 @@
1
+ from os.path import dirname, abspath
2
+ import sys
3
+ from importlib import import_module
4
+
5
+ from hestia_earth.models.utils.blank_node import run_if_required
6
+
7
+ CURRENT_DIR = dirname(abspath(__file__)) + '/'
8
+ sys.path.append(CURRENT_DIR)
9
+ MODEL = 'frischknechtEtAl2000'
10
+ PKG = '.'.join(['hestia_earth', 'models', MODEL])
11
+
12
+
13
+ def run(model: str, data): return run_if_required(MODEL, model, data, import_module(f".{model}", package=PKG))
@@ -0,0 +1,90 @@
1
+ from functools import reduce
2
+ from hestia_earth.schema import TermTermType
3
+ from hestia_earth.utils.tools import list_sum, flatten, non_empty_list
4
+
5
+ from hestia_earth.models.log import logRequirements, logShouldRun
6
+ from hestia_earth.models.utils.emission import filter_emission_inputs
7
+ from hestia_earth.models.utils.indicator import _new_indicator
8
+ from hestia_earth.models.utils.lookup import factor_value
9
+ from . import MODEL
10
+
11
+ REQUIREMENTS = {
12
+ "ImpactAssessment": {
13
+ "emissionsResourceUse": [{
14
+ "@type": "Indicator",
15
+ "value": "",
16
+ "term.@id": [
17
+ "ionisingCompoundsToAirInputsProduction",
18
+ "ionisingCompoundsToWaterInputsProduction",
19
+ "ionisingCompoundsToSaltwaterInputsProduction"
20
+ ],
21
+ "inputs": [{"@type": "Input", "term.termType": "waste"}]
22
+ }]
23
+ }
24
+ }
25
+ LOOKUPS = {
26
+ "waste": [
27
+ "ionisingCompoundsToAirInputsProduction",
28
+ "ionisingCompoundsToWaterInputsProduction",
29
+ "ionisingCompoundsToSaltwaterInputsProduction"
30
+ ]
31
+ }
32
+ RETURNS = {
33
+ "Indicator": {
34
+ "value": "",
35
+ "inputs": ""
36
+ }
37
+ }
38
+
39
+ TERM_ID = 'ionisingRadiationKbqU235Eq'
40
+
41
+
42
+ def _indicator(value: float, input: dict):
43
+ indicator = _new_indicator(TERM_ID, MODEL)
44
+ indicator['value'] = value
45
+ indicator['inputs'] = [input]
46
+ return indicator
47
+
48
+
49
+ def _run(grouped_emissions_inputs: list):
50
+ input = grouped_emissions_inputs[0].get('input')
51
+ values = [
52
+ factor_value(
53
+ model=MODEL,
54
+ term_id=TERM_ID,
55
+ lookup_name=f"{TermTermType.WASTE.value}.csv",
56
+ lookup_col=i.get('emission').get('term', {}).get('@id')
57
+ )(data=i.get('emission') | {'term': i.get('input')})
58
+ for i in grouped_emissions_inputs
59
+ ]
60
+ value = list_sum(values)
61
+ return _indicator(value, input) if value else None
62
+
63
+
64
+ def _should_run(impact_assessment: dict):
65
+ emissions = flatten([
66
+ ([
67
+ {'emission': emission, 'input': input}
68
+ for input in filter_emission_inputs(emission, TermTermType.WASTE)
69
+ ])
70
+ for emission in impact_assessment.get('emissionsResourceUse', [])
71
+ if emission.get('term', {}).get('@id') in LOOKUPS[TermTermType.WASTE.value]
72
+ ])
73
+ emissions_per_input = reduce(
74
+ lambda p, c: p | {c.get('input').get('@id'): p.get(c.get('input').get('@id'), []) + [c]},
75
+ emissions,
76
+ {}
77
+ )
78
+
79
+ logRequirements(impact_assessment, model=MODEL,
80
+ has_emissions=bool(emissions_per_input))
81
+
82
+ should_run = all([emissions_per_input])
83
+
84
+ logShouldRun(impact_assessment, MODEL, TERM_ID, should_run)
85
+ return should_run, emissions_per_input
86
+
87
+
88
+ def run(impact_assessment: dict):
89
+ should_run, emissions_per_input = _should_run(impact_assessment)
90
+ return non_empty_list(map(_run, emissions_per_input.values())) if should_run else []