hestia-earth-models 0.74.4__py3-none-any.whl → 0.74.6__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 (66) hide show
  1. hestia_earth/models/cml2001Baseline/abioticResourceDepletionMineralsAndMetals.py +0 -1
  2. hestia_earth/models/config/Cycle.json +15 -0
  3. hestia_earth/models/config/ImpactAssessment.json +9 -1
  4. hestia_earth/models/cycle/animal/input/hestiaAggregatedData.py +3 -3
  5. hestia_earth/models/cycle/completeness/seed.py +1 -1
  6. hestia_earth/models/cycle/input/hestiaAggregatedData.py +25 -16
  7. hestia_earth/models/data/hestiaAggregatedData/__init__.py +73 -0
  8. hestia_earth/models/environmentalFootprintV3_1/scarcityWeightedWaterUse.py +1 -1
  9. hestia_earth/models/environmentalFootprintV3_1/soilQualityIndexLandOccupation.py +5 -6
  10. hestia_earth/models/environmentalFootprintV3_1/soilQualityIndexLandTransformation.py +10 -13
  11. hestia_earth/models/fantkeEtAl2016/damageToHumanHealthParticulateMatterFormation.py +1 -1
  12. hestia_earth/models/hestia/default_resourceUse.py +18 -16
  13. hestia_earth/models/hestia/landCover.py +24 -0
  14. hestia_earth/models/hestia/landOccupationDuringCycle.py +80 -51
  15. hestia_earth/models/hestia/landTransformation100YearAverageDuringCycle.py +7 -1
  16. hestia_earth/models/hestia/landTransformation20YearAverageDuringCycle.py +7 -1
  17. hestia_earth/models/hestia/resourceUse_utils.py +58 -119
  18. hestia_earth/models/hestia/waterSalinity.py +57 -12
  19. hestia_earth/models/impact_assessment/post_checks/__init__.py +3 -2
  20. hestia_earth/models/impact_assessment/post_checks/remove_cache_fields.py +9 -0
  21. hestia_earth/models/impact_assessment/pre_checks/cache_emissionsResourceUse.py +21 -0
  22. hestia_earth/models/impact_assessment/pre_checks/cycle.py +5 -0
  23. hestia_earth/models/ipcc2019/co2ToAirAboveGroundBiomassStockChange.py +6 -64
  24. hestia_earth/models/ipcc2019/co2ToAirBelowGroundBiomassStockChange.py +9 -87
  25. hestia_earth/models/ipcc2019/co2ToAirBiocharStockChange.py +140 -0
  26. hestia_earth/models/ipcc2019/co2ToAirCarbonStockChange_utils.py +329 -217
  27. hestia_earth/models/ipcc2019/co2ToAirSoilOrganicCarbonStockChange.py +10 -87
  28. hestia_earth/models/mocking/__init__.py +2 -2
  29. hestia_earth/models/mocking/mock_search.py +20 -10
  30. hestia_earth/models/mocking/search-results.json +1 -7679
  31. hestia_earth/models/pooreNemecek2018/landOccupationDuringCycle.py +8 -7
  32. hestia_earth/models/poschEtAl2008/terrestrialAcidificationPotentialAccumulatedExceedance.py +1 -1
  33. hestia_earth/models/poschEtAl2008/terrestrialEutrophicationPotentialAccumulatedExceedance.py +1 -1
  34. hestia_earth/models/preload_requests.py +18 -4
  35. hestia_earth/models/schmidt2007/utils.py +3 -3
  36. hestia_earth/models/utils/__init__.py +4 -1
  37. hestia_earth/models/utils/aggregated.py +21 -68
  38. hestia_earth/models/utils/cycle.py +3 -3
  39. hestia_earth/models/utils/impact_assessment.py +45 -41
  40. hestia_earth/models/utils/indicator.py +1 -3
  41. hestia_earth/models/utils/lookup.py +92 -67
  42. hestia_earth/models/version.py +1 -1
  43. hestia_earth/orchestrator/models/__init__.py +47 -10
  44. hestia_earth/orchestrator/models/transformations.py +3 -1
  45. hestia_earth/orchestrator/strategies/merge/__init__.py +1 -2
  46. hestia_earth/orchestrator/strategies/merge/merge_list.py +31 -8
  47. hestia_earth/orchestrator/utils.py +29 -0
  48. {hestia_earth_models-0.74.4.dist-info → hestia_earth_models-0.74.6.dist-info}/METADATA +2 -3
  49. {hestia_earth_models-0.74.4.dist-info → hestia_earth_models-0.74.6.dist-info}/RECORD +66 -59
  50. tests/models/cycle/animal/input/test_hestiaAggregatedData.py +3 -3
  51. tests/models/cycle/input/test_hestiaAggregatedData.py +9 -18
  52. tests/models/data/__init__.py +0 -0
  53. tests/models/data/test_hestiaAggregatedData.py +32 -0
  54. tests/models/hestia/test_default_emissions.py +8 -1
  55. tests/models/hestia/test_default_resourceUse.py +7 -1
  56. tests/models/hestia/test_landCover.py +32 -1
  57. tests/models/hestia/test_waterSalinity.py +16 -4
  58. tests/models/ipcc2019/test_co2ToAirAboveGroundBiomassStockChange.py +1 -6
  59. tests/models/ipcc2019/test_co2ToAirBelowGroundBiomassStockChange.py +1 -6
  60. tests/models/ipcc2019/test_co2ToAirBiocharStockChange.py +90 -0
  61. tests/models/ipcc2019/test_co2ToAirSoilOrganicCarbonStockChange.py +1 -6
  62. tests/models/pooreNemecek2018/test_landOccupationDuringCycle.py +1 -0
  63. tests/orchestrator/strategies/merge/test_merge_list.py +5 -0
  64. {hestia_earth_models-0.74.4.dist-info → hestia_earth_models-0.74.6.dist-info}/LICENSE +0 -0
  65. {hestia_earth_models-0.74.4.dist-info → hestia_earth_models-0.74.6.dist-info}/WHEEL +0 -0
  66. {hestia_earth_models-0.74.4.dist-info → hestia_earth_models-0.74.6.dist-info}/top_level.txt +0 -0
@@ -80,7 +80,6 @@ def _should_run(impact_assessment: dict) -> tuple[bool, list]:
80
80
  "input-term-type": input.get('termType'),
81
81
  "indicator-term-id": resource_indicator['term']['@id'],
82
82
  "indicator-is-valid": _valid_resource_indicator(resource_indicator),
83
- "input": input,
84
83
  "indicator-input-is-valid": _valid_input(input),
85
84
  "value": _node_value(resource_indicator),
86
85
  "coefficient": get_table_value(
@@ -1264,6 +1264,21 @@
1264
1264
  },
1265
1265
  "stage": 2
1266
1266
  },
1267
+ {
1268
+ "key": "emissions",
1269
+ "model": "ipcc2019",
1270
+ "value": "co2ToAirBiocharStockChange",
1271
+ "runStrategy": "add_blank_node_if_missing",
1272
+ "runArgs": {
1273
+ "runNonMeasured": true,
1274
+ "runNonAddedTerm": true
1275
+ },
1276
+ "mergeStrategy": "list",
1277
+ "mergeArgs": {
1278
+ "replaceThreshold": ["value", 0.01]
1279
+ },
1280
+ "stage": 2
1281
+ },
1267
1282
  {
1268
1283
  "key": "emissions",
1269
1284
  "model": "ipcc2019",
@@ -82,7 +82,7 @@
82
82
  "key": "emissionsResourceUse",
83
83
  "model": "pooreNemecek2018",
84
84
  "value": "landOccupationDuringCycle",
85
- "runStrategy": "always",
85
+ "runStrategy": "add_blank_node_if_missing",
86
86
  "mergeStrategy": "list",
87
87
  "mergeArgs": {
88
88
  "replaceThreshold": ["value", 0.01]
@@ -225,6 +225,14 @@
225
225
  },
226
226
  "stage": 1
227
227
  },
228
+ {
229
+ "key": "cache_emissionsResourceUse",
230
+ "model": "impact_assessment",
231
+ "value": "pre_checks.cache_emissionsResourceUse",
232
+ "runStrategy": "always",
233
+ "mergeStrategy": "default",
234
+ "stage": 1
235
+ },
228
236
  {
229
237
  "key": "impacts",
230
238
  "model": "ipcc2021",
@@ -34,8 +34,8 @@ MODEL_ID = 'hestiaAggregatedData'
34
34
  MODEL_KEY = 'impactAssessment'
35
35
 
36
36
 
37
- def _run_animal_input(cycle: dict, input: dict):
38
- inputs = link_inputs_to_impact(MODEL_ID, cycle, [input])
37
+ def _run_animal_input(cycle: dict, animal: dict, input: dict):
38
+ inputs = link_inputs_to_impact(MODEL_ID, cycle, [input], animalId=animal.get('animalId'))
39
39
  return inputs[0] if inputs else input
40
40
 
41
41
 
@@ -43,7 +43,7 @@ def _run_animal(cycle: dict, animal: dict):
43
43
  return animal | {
44
44
  'inputs': [
45
45
  (
46
- _run_animal_input(cycle, input) if should_link_input_to_impact(cycle)(input) else input
46
+ _run_animal_input(cycle, animal, input) if should_link_input_to_impact(cycle)(input) else input
47
47
  ) for input in animal.get('inputs', [])
48
48
  ]
49
49
  }
@@ -36,7 +36,7 @@ def run(cycle: dict):
36
36
  site_type = cycle.get('site', {}).get('siteType')
37
37
  site_type_allowed = site_type in ALLOWED_SITE_TYPES
38
38
 
39
- has_seed = find_term_match(cycle.get('inputs', []), 'seed', None)
39
+ has_seed = find_term_match(cycle.get('inputs', []), 'seed', None) is not None
40
40
 
41
41
  product = find_primary_product(cycle) or {}
42
42
  term_id = product.get('term', {}).get('@id')
@@ -1,12 +1,13 @@
1
- from hestia_earth.schema import TermTermType
1
+ from hestia_earth.schema import TermTermType, NodeType
2
2
  from hestia_earth.utils.model import find_primary_product, linked_node, filter_list_term_type
3
3
  from hestia_earth.utils.tools import non_empty_list
4
4
 
5
5
  from hestia_earth.models.log import debugValues, logRequirements, logShouldRun
6
+ from hestia_earth.models.data.hestiaAggregatedData import DEFAULT_COUNTRY_ID, find_closest_impact_id
6
7
  from hestia_earth.models.utils.crop import valid_site_type
7
- from hestia_earth.models.utils.term import get_lookup_value, get_generic_crop, download_term
8
+ from hestia_earth.models.utils.term import get_lookup_value, get_generic_crop
8
9
  from hestia_earth.models.utils.aggregated import (
9
- should_link_input_to_impact, link_inputs_to_impact, find_closest_impact, aggregated_end_date
10
+ should_link_input_to_impact, link_inputs_to_impact, aggregated_end_date
10
11
  )
11
12
 
12
13
  REQUIREMENTS = {
@@ -56,29 +57,37 @@ MODEL_KEY = 'impactAssessment'
56
57
 
57
58
 
58
59
  def _run_seed(cycle: dict, primary_product: dict, seed_input: dict, product_term_id: str):
59
- product = download_term(product_term_id, TermTermType.SEED)
60
60
  country = seed_input.get('country')
61
+ country_id = (country or {}).get('@id')
62
+
63
+ primary_product_id = primary_product.get('term', {}).get('@id')
64
+ default_product_id = get_generic_crop().get('@id')
65
+
61
66
  # to avoid double counting seed => aggregated impact => seed, we need to get the impact of the previous decade
62
67
  # if the data does not exist, use the aggregated impact of generic crop instead
63
- date = aggregated_end_date(cycle.get('endDate'))
64
- match_end_date = [{'match': {'endDate': date - 10}}]
65
- default_product = get_generic_crop()
66
-
67
- impact = (
68
- find_closest_impact(cycle, date, product, country, must_queries=match_end_date) or
69
- find_closest_impact(cycle, date, primary_product.get('term', {}), country, must_queries=match_end_date) or
70
- find_closest_impact(cycle, date, default_product, country)
68
+ date = aggregated_end_date(cycle.get('endDate')) - 10
69
+
70
+ impact_id = (
71
+ find_closest_impact_id(product_id=product_term_id, country_id=country_id, year=date) or
72
+ find_closest_impact_id(product_id=product_term_id, country_id=DEFAULT_COUNTRY_ID, year=date) or
73
+ find_closest_impact_id(product_id=primary_product_id, country_id=country_id, year=date) or
74
+ find_closest_impact_id(product_id=primary_product_id, country_id=DEFAULT_COUNTRY_ID, year=date) or
75
+ find_closest_impact_id(product_id=default_product_id, country_id=country_id, year=date) or
76
+ find_closest_impact_id(product_id=default_product_id, country_id=DEFAULT_COUNTRY_ID, year=date)
71
77
  )
72
78
 
73
- search_by_product_term_id = (product or primary_product or default_product).get('@id')
74
- search_by_country_id = (country or {}).get('@id') or 'region-world'
79
+ search_by_product_term_id = product_term_id or primary_product_id or default_product_id
80
+ search_by_country_id = country_id or DEFAULT_COUNTRY_ID
75
81
  debugValues(cycle, model=MODEL_ID, term=seed_input.get('term', {}).get('@id'), key=MODEL_KEY,
76
82
  search_by_product_term_id=search_by_product_term_id,
77
83
  search_by_country_id=search_by_country_id,
78
84
  search_by_end_date=str(date),
79
- impact_assessment_id_found=(impact or {}).get('@id'))
85
+ impact_assessment_id_found=impact_id)
80
86
 
81
- return seed_input | {MODEL_KEY: linked_node(impact), 'impactAssessmentIsProxy': True} if impact else None
87
+ return seed_input | {
88
+ MODEL_KEY: linked_node({'@type': NodeType.IMPACTASSESSMENT.value, '@id': impact_id}),
89
+ 'impactAssessmentIsProxy': True
90
+ } if impact_id else None
82
91
 
83
92
 
84
93
  def _should_run_seed(cycle: dict):
@@ -0,0 +1,73 @@
1
+ import os
2
+ import json
3
+ from datetime import datetime
4
+ from hestia_earth.utils.storage._s3_client import _load_from_bucket
5
+ from hestia_earth.utils.api import _safe_get_request
6
+
7
+ _CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
8
+ _FILENAME = 'hestiaAggregatedData.json'
9
+ FILEPATH = os.path.join(_CURRENT_DIR, _FILENAME)
10
+ _CACHED_DATA = {}
11
+ DEFAULT_COUNTRY_ID = 'region-world'
12
+
13
+
14
+ def _today(): return datetime.now().strftime('%Y-%m-%d')
15
+
16
+
17
+ def _download_data():
18
+ try:
19
+ return json.loads(_load_from_bucket('hestia-data', os.path.join('data', _FILENAME)))
20
+ except Exception:
21
+ return _safe_get_request(f"https://hestia.earth/data/{_FILENAME}")
22
+
23
+
24
+ def _load_data():
25
+ data = None
26
+
27
+ if os.path.exists(FILEPATH):
28
+ with open(FILEPATH, 'r') as f:
29
+ data = json.load(f)
30
+
31
+ is_data_valid = data and data['date'] == _today()
32
+
33
+ if not is_data_valid:
34
+ data = _download_data()
35
+ with open(FILEPATH, 'w') as f:
36
+ f.write(json.dumps(data))
37
+
38
+ return data
39
+
40
+
41
+ def _get_data():
42
+ global _CACHED_DATA # noqa: F824
43
+ if not _CACHED_DATA or _CACHED_DATA['date'] != _today():
44
+ _CACHED_DATA = _load_data()
45
+ return _CACHED_DATA
46
+
47
+
48
+ def _get_closest_id(data: dict, year: int):
49
+ available_years = [int(y) for y in data.keys() if int(y) <= year]
50
+ return data[str(sorted(available_years, reverse=True)[0])] if available_years else None
51
+
52
+
53
+ def find_closest_impact_id(product_id: str, country_id: str, year: int):
54
+ """
55
+ Find the `@id` of the closest ImpactAssessment to the target year.
56
+
57
+ Parameters
58
+ ----------
59
+ product_id : str
60
+ The `@id` of the product (Term).
61
+ country_id : str
62
+ The `@id` of the country (Term).
63
+ year : int
64
+ The target year.
65
+
66
+ Returns
67
+ -------
68
+ str
69
+ The `@id` as a string if found.
70
+ """
71
+ data = _get_data()
72
+ values = data.get(product_id, {}).get(country_id, {})
73
+ return _get_closest_id(data=values, year=year)
@@ -33,7 +33,7 @@ def _indicator(value: float):
33
33
 
34
34
  def run(impact_assessment: dict):
35
35
  value = impact_country_value(MODEL, TERM_ID, impact_assessment, f"{list(LOOKUPS.keys())[0]}.csv",
36
- country_fallback=True)
36
+ default_world_value=True)
37
37
  logRequirements(impact_assessment, model=MODEL, term=TERM_ID,
38
38
  value=value)
39
39
  logShouldRun(impact_assessment, MODEL, TERM_ID, value is not None)
@@ -7,7 +7,7 @@ from hestia_earth.utils.tools import list_sum
7
7
  from hestia_earth.models.log import logRequirements, logShouldRun, log_as_table
8
8
  from hestia_earth.models.utils.indicator import _new_indicator
9
9
  from hestia_earth.models.utils.landCover import get_pef_grouping
10
- from hestia_earth.models.utils.lookup import fallback_country, _node_value, get_region_lookup_value
10
+ from hestia_earth.models.utils.lookup import _node_value, get_region_lookup_value
11
11
  from . import MODEL
12
12
  from ..utils.impact_assessment import get_country_id
13
13
 
@@ -68,7 +68,6 @@ def _should_run(impact_assessment: dict) -> Tuple[bool, list]:
68
68
  'area-by-year-is-valid': _node_value(indicator) is not None and _node_value(
69
69
  indicator) >= 0,
70
70
  'area-unit-is-valid': indicator.get('term', {}).get("units") == "m2*year",
71
- 'used-country': fallback_country(get_country_id(impact_assessment, blank_node=indicator), [LOOKUP]),
72
71
  'pef-grouping': get_pef_grouping(indicator.get('landCover', {}).get("@id"))
73
72
 
74
73
  } for indicator in land_occupation_indicators]
@@ -79,10 +78,10 @@ def _should_run(impact_assessment: dict) -> Tuple[bool, list]:
79
78
  model=MODEL,
80
79
  term=TERM_ID,
81
80
  lookup_name=LOOKUP,
82
- term_id=indicator['used-country'],
83
- column=indicator['pef-grouping']
84
- ),
85
- "using-fallback-country-region-world-CFs": indicator['used-country'] != indicator['country-id']
81
+ term_id=indicator['country-id'],
82
+ column=indicator['pef-grouping'],
83
+ fallback_world=True
84
+ )
86
85
  } for indicator in found_land_occupation_indicators
87
86
  ]
88
87
 
@@ -8,7 +8,7 @@ from hestia_earth.models.log import logRequirements, logShouldRun, log_as_table
8
8
  from hestia_earth.models.utils.impact_assessment import get_country_id
9
9
  from hestia_earth.models.utils.indicator import _new_indicator
10
10
  from hestia_earth.models.utils.landCover import get_pef_grouping
11
- from hestia_earth.models.utils.lookup import fallback_country, _node_value, get_region_lookup_value
11
+ from hestia_earth.models.utils.lookup import _node_value, get_region_lookup_value
12
12
  from . import MODEL
13
13
 
14
14
  REQUIREMENTS = {
@@ -104,31 +104,28 @@ def _should_run(impact_assessment: dict) -> Tuple[bool, list]:
104
104
  'value-is-valid': (
105
105
  _node_value(indicator) is not None and
106
106
  _node_value(indicator) >= 0
107
- ),
108
- 'lookup-country': fallback_country(
109
- get_country_id(impact_assessment, blank_node=indicator),
110
- [from_lookup_file, to_lookup_file]
111
- ),
107
+ )
112
108
  } for indicator in resource_uses
113
109
  ]
114
110
 
115
111
  found_transformations_with_coefficient = [
116
112
  transformation | {
117
- 'using-fallback-country-region-world-CFs': transformation['lookup-country'] != transformation['country-id'],
118
113
  'factor-from': get_region_lookup_value(
119
114
  model=MODEL,
120
115
  term=TERM_ID,
121
116
  lookup_name=from_lookup_file,
122
- term_id=transformation['lookup-country'],
123
- column=get_pef_grouping(transformation['land-cover-id-from'])) if
124
- transformation['land-cover-id-from'] else None,
117
+ term_id=transformation['country-id'],
118
+ column=get_pef_grouping(transformation['land-cover-id-from']),
119
+ fallback_world=True
120
+ ) if transformation['land-cover-id-from'] else None,
125
121
  'factor-to': get_region_lookup_value(
126
122
  model=MODEL,
127
123
  term=TERM_ID,
128
124
  lookup_name=to_lookup_file,
129
- term_id=transformation['lookup-country'],
130
- column=get_pef_grouping(transformation['land-cover-id-to'])) if
131
- transformation['land-cover-id-to'] else None
125
+ term_id=transformation['country-id'],
126
+ column=get_pef_grouping(transformation['land-cover-id-to']),
127
+ fallback_world=True
128
+ ) if transformation['land-cover-id-to'] else None
132
129
  } for transformation in found_transformations
133
130
  ]
134
131
 
@@ -28,7 +28,7 @@ def _indicator(value: float):
28
28
 
29
29
  def run(impact_assessment: dict):
30
30
  value = impact_emission_lookup_value(
31
- model=MODEL, term_id=TERM_ID, impact=impact_assessment, lookup_col=LOOKUPS['emission'], grouped_key='default'
31
+ model=MODEL, term_id=TERM_ID, impact=impact_assessment, lookup_col=LOOKUPS['emission'], group_key='default'
32
32
  )
33
33
  logRequirements(impact_assessment, model=MODEL, term=TERM_ID,
34
34
  value=value)
@@ -1,4 +1,4 @@
1
- from hestia_earth.schema import IndicatorMethodTier, TermTermType
1
+ from hestia_earth.schema import TermTermType
2
2
  from hestia_earth.utils.tools import flatten, safe_parse_float
3
3
 
4
4
  from hestia_earth.models.log import logRequirements, logShouldRun, debugValues
@@ -8,6 +8,8 @@ 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
10
10
  from hestia_earth.models.utils.input import unique_background_inputs
11
+ from hestia_earth.models.utils.impact_assessment import get_product
12
+ from hestia_earth.models.utils.crop import get_landCover_term_id
11
13
  from . import MODEL
12
14
 
13
15
  REQUIREMENTS = {
@@ -29,8 +31,7 @@ REQUIREMENTS = {
29
31
  RETURNS = {
30
32
  "Indicator": [{
31
33
  "value": "",
32
- "inputs": "",
33
- "methodTier": "background"
34
+ "inputs": ""
34
35
  }]
35
36
  }
36
37
  LOOKUPS = {
@@ -38,14 +39,12 @@ LOOKUPS = {
38
39
  "organicFertiliser": "backgroundEmissionsResourceUseDefaultValue"
39
40
  }
40
41
  MODEL_KEY = 'default_resourceUse'
41
- TIER = IndicatorMethodTier.BACKGROUND.value
42
42
 
43
43
 
44
- def _indicator(term_id: str, value: float, input: dict):
45
- indicator = _new_indicator(term_id, MODEL)
44
+ def _indicator(term_id: str, value: float, input: dict, land_cover_id: str):
45
+ indicator = _new_indicator(term_id, MODEL, land_cover_id)
46
46
  indicator['value'] = value
47
47
  indicator['inputs'] = [input]
48
- indicator['methodTier'] = TIER
49
48
  return indicator
50
49
 
51
50
 
@@ -53,7 +52,7 @@ def _default_value(input: dict):
53
52
  return safe_parse_float(get_lookup_value(input.get('term', {}), LOOKUPS['organicFertiliser']), default=None)
54
53
 
55
54
 
56
- def _run_input(impact: dict):
55
+ def _run_input(impact: dict, land_cover_id: str):
57
56
  required_resourceUse_term_ids = background_emissions_in_system_boundary(impact, TermTermType.RESOURCEUSE)
58
57
 
59
58
  def run(input: dict):
@@ -62,14 +61,14 @@ def _run_input(impact: dict):
62
61
  value = input.get('default-value-from-lookup')
63
62
 
64
63
  for emission_id in required_resourceUse_term_ids:
65
- logShouldRun(impact, MODEL, term_id, True, methodTier=TIER, model_key=MODEL_KEY, emission_id=emission_id)
64
+ logShouldRun(impact, MODEL, term_id, True, model_key=MODEL_KEY, emission_id=emission_id)
66
65
  debugValues(impact, model=MODEL, term=emission_id,
67
66
  value=value,
68
67
  coefficient=1,
69
68
  input=term_id)
70
69
 
71
70
  return [
72
- _indicator(term_id, value, input_term) for term_id in required_resourceUse_term_ids
71
+ _indicator(term_id, value, input_term, land_cover_id) for term_id in required_resourceUse_term_ids
73
72
  ]
74
73
 
75
74
  return run
@@ -95,18 +94,21 @@ def _should_run(impact: dict):
95
94
  ])
96
95
  ]
97
96
 
98
- should_run = all([bool(valid_inputs)])
97
+ landCover_term_id = get_landCover_term_id(get_product(impact).get("term", {}))
98
+
99
+ should_run = all([bool(valid_inputs), landCover_term_id])
99
100
 
100
101
  for input in inputs:
101
102
  term_id = input.get('input').get('term', {}).get('@id')
102
103
 
103
104
  logRequirements(impact, model=MODEL, term=term_id, model_key=MODEL_KEY,
104
- **_omit(input, ['input', 'input-value']))
105
- logShouldRun(impact, MODEL, term_id, should_run, methodTier=TIER, model_key=MODEL_KEY)
105
+ **_omit(input, ['input', 'input-value']),
106
+ landCover_term_id=landCover_term_id)
107
+ logShouldRun(impact, MODEL, term_id, should_run, model_key=MODEL_KEY)
106
108
 
107
- return should_run, valid_inputs
109
+ return should_run, valid_inputs, landCover_term_id
108
110
 
109
111
 
110
112
  def run(impact: dict):
111
- should_run, grouped_inputs = _should_run(impact)
112
- return flatten(map(_run_input(impact), grouped_inputs)) if should_run else []
113
+ should_run, grouped_inputs, landCover_term_id = _should_run(impact)
114
+ return flatten(map(_run_input(impact, landCover_term_id), grouped_inputs)) if should_run else []
@@ -750,6 +750,22 @@ def _should_run_historical_land_use_change_total_cropland(site: dict, nodes: lis
750
750
  return all([should_run_annual, should_run_permanent]), scaled_results
751
751
 
752
752
 
753
+ def _log_all_terms(site: dict, land_use_type: str, country_id: str, changes: dict, missing_changes: list):
754
+ for land_use_term, _ in LAND_USE_TERMS_FOR_TRANSFORMATION.values():
755
+ logRequirements(
756
+ log_node=site,
757
+ model=MODEL,
758
+ term=land_use_term,
759
+ model_key=MODEL_KEY,
760
+ land_use_type=land_use_type,
761
+ country_id=country_id,
762
+ changes=log_as_table(changes),
763
+ missing_changes=log_as_table(missing_changes)
764
+ )
765
+
766
+ logShouldRun(site, MODEL, land_use_term, False, model_key=MODEL_KEY)
767
+
768
+
753
769
  def _should_run_historical_land_use_change_single_crop(
754
770
  site: dict,
755
771
  term: dict,
@@ -909,6 +925,14 @@ def _should_run_historical_land_use_change_single_crop(
909
925
 
910
926
  should_run = all([len(missing_changes) == 0, country_id, site_type_allowed, sum_of_site_areas_is_100])
911
927
  logShouldRun(site, MODEL, term.get("@id"), should_run, model_key=MODEL_KEY)
928
+ if not should_run:
929
+ _log_all_terms(
930
+ site=site,
931
+ land_use_type=land_use_type,
932
+ country_id=country_id,
933
+ changes=changes,
934
+ missing_changes=missing_changes
935
+ )
912
936
 
913
937
  return should_run, capped_site_area
914
938