hestia-earth-models 0.62.0__py3-none-any.whl → 0.62.1__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 (58) hide show
  1. hestia_earth/models/blonkConsultants2016/utils.py +3 -2
  2. hestia_earth/models/cycle/post_checks/__init__.py +3 -2
  3. hestia_earth/models/cycle/post_checks/otherSites.py +40 -0
  4. hestia_earth/models/cycle/pre_checks/__init__.py +2 -1
  5. hestia_earth/models/cycle/pre_checks/otherSites.py +42 -0
  6. hestia_earth/models/cycle/pre_checks/site.py +1 -1
  7. hestia_earth/models/ecoinventV3AndEmberClimate/utils.py +1 -1
  8. hestia_earth/models/emepEea2019/utils.py +4 -3
  9. hestia_earth/models/geospatialDatabase/heavyWinterPrecipitation.py +1 -1
  10. hestia_earth/models/ipcc2019/animal/pastureGrass.py +6 -6
  11. hestia_earth/models/ipcc2019/co2ToAirSoilOrganicCarbonStockChangeManagementChange.py +30 -4
  12. hestia_earth/models/ipcc2019/n2OToAirExcretaDirect.py +6 -2
  13. hestia_earth/models/ipcc2019/n2OToAirExcretaIndirect.py +1 -1
  14. hestia_earth/models/ipcc2019/n2OToAirInorganicFertiliserDirect.py +1 -1
  15. hestia_earth/models/ipcc2019/n2OToAirInorganicFertiliserIndirect.py +1 -1
  16. hestia_earth/models/ipcc2019/n2OToAirOrganicFertiliserIndirect.py +1 -1
  17. hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_1_utils.py +4 -2
  18. hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_2_utils.py +2 -1
  19. hestia_earth/models/ipcc2019/pastureGrass.py +3 -3
  20. hestia_earth/models/ipcc2019/pastureGrass_utils.py +41 -41
  21. hestia_earth/models/mocking/search-results.json +89 -89
  22. hestia_earth/models/schererPfister2015/utils.py +2 -2
  23. hestia_earth/models/site/brackishWater.py +1 -1
  24. hestia_earth/models/site/flowingWater.py +1 -1
  25. hestia_earth/models/site/freshWater.py +1 -1
  26. hestia_earth/models/site/management.py +29 -11
  27. hestia_earth/models/site/pre_checks/cache_sources.py +9 -13
  28. hestia_earth/models/site/salineWater.py +1 -1
  29. hestia_earth/models/stehfestBouwman2006/n2OToAirCropResidueDecompositionDirect.py +12 -2
  30. hestia_earth/models/stehfestBouwman2006/n2OToAirExcretaDirect.py +12 -2
  31. hestia_earth/models/stehfestBouwman2006/n2OToAirInorganicFertiliserDirect.py +11 -1
  32. hestia_earth/models/stehfestBouwman2006/n2OToAirOrganicFertiliserDirect.py +11 -1
  33. hestia_earth/models/stehfestBouwman2006/noxToAirCropResidueDecomposition.py +12 -2
  34. hestia_earth/models/stehfestBouwman2006/noxToAirExcreta.py +12 -2
  35. hestia_earth/models/stehfestBouwman2006/noxToAirInorganicFertiliser.py +11 -1
  36. hestia_earth/models/stehfestBouwman2006/noxToAirOrganicFertiliser.py +11 -1
  37. hestia_earth/models/stehfestBouwman2006GisImplementation/noxToAirCropResidueDecomposition.py +12 -2
  38. hestia_earth/models/stehfestBouwman2006GisImplementation/noxToAirExcreta.py +12 -2
  39. hestia_earth/models/stehfestBouwman2006GisImplementation/noxToAirInorganicFertiliser.py +11 -1
  40. hestia_earth/models/stehfestBouwman2006GisImplementation/noxToAirOrganicFertiliser.py +11 -1
  41. hestia_earth/models/utils/blank_node.py +106 -110
  42. hestia_earth/models/utils/constant.py +2 -0
  43. hestia_earth/models/utils/lookup.py +19 -6
  44. hestia_earth/models/utils/source.py +1 -1
  45. hestia_earth/models/version.py +1 -1
  46. {hestia_earth_models-0.62.0.dist-info → hestia_earth_models-0.62.1.dist-info}/METADATA +2 -2
  47. {hestia_earth_models-0.62.0.dist-info → hestia_earth_models-0.62.1.dist-info}/RECORD +58 -53
  48. tests/models/cycle/post_checks/test_otherSites.py +15 -0
  49. tests/models/cycle/pre_checks/test_otherSites.py +21 -0
  50. tests/models/ipcc2019/test_co2ToAirSoilOrganicCarbonStockChangeManagementChange.py +5 -3
  51. tests/models/ipcc2019/test_organicCarbonPerHa.py +1 -0
  52. tests/models/site/pre_checks/test_cache_sources.py +6 -10
  53. tests/models/site/test_management.py +162 -2
  54. tests/models/utils/test_blank_node.py +0 -281
  55. tests/models/utils/test_lookup.py +10 -0
  56. {hestia_earth_models-0.62.0.dist-info → hestia_earth_models-0.62.1.dist-info}/LICENSE +0 -0
  57. {hestia_earth_models-0.62.0.dist-info → hestia_earth_models-0.62.1.dist-info}/WHEEL +0 -0
  58. {hestia_earth_models-0.62.0.dist-info → hestia_earth_models-0.62.1.dist-info}/top_level.txt +0 -0
@@ -25,5 +25,6 @@ def get_emission_factor(term_id: str, cycle: dict, factor: str):
25
25
  data = safe_parse_float(value, None)
26
26
  # fallback to site.siteType data if possible
27
27
  return data if data is not None else safe_parse_float(
28
- extract_grouped_data(
29
- get_table_value(lookup, 'termid', country_id, column_name('NONE')), site.get('siteType')), None)
28
+ extract_grouped_data(get_table_value(lookup, 'termid', country_id, column_name('NONE')), site.get('siteType')),
29
+ None
30
+ )
@@ -2,14 +2,15 @@ from os.path import dirname, abspath
2
2
  import sys
3
3
 
4
4
  from hestia_earth.models.utils import _run_in_serie
5
- from . import cache, site
5
+ from . import cache, site, otherSites
6
6
 
7
7
  CURRENT_DIR = dirname(abspath(__file__)) + '/'
8
8
  sys.path.append(CURRENT_DIR)
9
9
 
10
10
  MODELS = [
11
11
  cache.run,
12
- site.run
12
+ site.run,
13
+ otherSites.run
13
14
  ]
14
15
 
15
16
 
@@ -0,0 +1,40 @@
1
+ """
2
+ Post Checks Other Sites
3
+
4
+ This model is run only if the [pre model](../pre_checks/cycle.md) has been run before.
5
+ This model will restore the `cycle.otherSites` as a list of "linked node"
6
+ (i.e. it will be set with only `@type`, `@id` and `name` keys).
7
+ """
8
+ from hestia_earth.utils.model import linked_node
9
+
10
+ REQUIREMENTS = {
11
+ "Cycle": {
12
+ "otherSites": [{
13
+ "@type": "Site",
14
+ "@id": ""
15
+ }]
16
+ }
17
+ }
18
+ RETURNS = {
19
+ "Cycle": {
20
+ "otherSites": [{"@type": "Site"}]
21
+ }
22
+ }
23
+ MODEL_KEY = 'otherSites'
24
+
25
+
26
+ def _run_site(site: dict): return linked_node(site)
27
+
28
+
29
+ def _should_run_site(site: dict): return site.get('@id') is not None
30
+
31
+
32
+ def _should_run(cycle: dict): return len(cycle.get(MODEL_KEY, [])) > 0
33
+
34
+
35
+ def run(cycle: dict):
36
+ return cycle | (
37
+ ({
38
+ MODEL_KEY: [_run_site(site) if _should_run_site(site) else site for site in cycle.get(MODEL_KEY, [])]
39
+ }) if _should_run(cycle) else {}
40
+ )
@@ -2,12 +2,13 @@ from os.path import dirname, abspath
2
2
  import sys
3
3
 
4
4
  from hestia_earth.models.utils import _run_in_serie
5
- from . import site, cache_sources
5
+ from . import site, cache_sources, otherSites
6
6
 
7
7
  CURRENT_DIR = dirname(abspath(__file__)) + '/'
8
8
  sys.path.append(CURRENT_DIR)
9
9
 
10
10
  MODELS = [
11
+ otherSites.run,
11
12
  site.run,
12
13
  cache_sources.run
13
14
  ]
@@ -0,0 +1,42 @@
1
+ """
2
+ Pre Checks Other Sites
3
+
4
+ Some Cycle models need a full version of the linked [Site](https://hestia.earth/schema/Site) to run.
5
+ This model will fetch the complete version of the [Cycle Sites](https://hestia.earth/schema/Cycle#otherSites)
6
+ and include them.
7
+ """
8
+ from hestia_earth.schema import SchemaType
9
+
10
+ from hestia_earth.models.utils import _load_calculated_node
11
+
12
+ REQUIREMENTS = {
13
+ "Cycle": {
14
+ "otherSites": [{
15
+ "@type": "Site",
16
+ "@id": ""
17
+ }]
18
+ }
19
+ }
20
+ RETURNS = {
21
+ "Cycle": {
22
+ "otherSites": [{"@type": "Site"}]
23
+ }
24
+ }
25
+ MODEL_KEY = 'otherSites'
26
+
27
+
28
+ def _run_site(site: dict): return _load_calculated_node(site, SchemaType.SITE)
29
+
30
+
31
+ def _should_run_site(site: dict): return site.get('@id') is not None
32
+
33
+
34
+ def _should_run(cycle: dict): return len(cycle.get(MODEL_KEY, [])) > 0
35
+
36
+
37
+ def run(cycle: dict):
38
+ return cycle | (
39
+ ({
40
+ MODEL_KEY: [_run_site(site) if _should_run_site(site) else site for site in cycle.get(MODEL_KEY, [])]
41
+ }) if _should_run(cycle) else {}
42
+ )
@@ -2,7 +2,7 @@
2
2
  Pre Checks Site
3
3
 
4
4
  Some Cycle models need a full version of the linked [Site](https://hestia.earth/schema/Site) to run.
5
- This model will fetch the complete version of the [Site](https://hestia.earth/schema/Site) and include it.
5
+ This model will fetch the complete version of the [Cycle Site](https://hestia.earth/schema/Cycle#site) and include it.
6
6
  """
7
7
  from hestia_earth.schema import SchemaType
8
8
 
@@ -33,7 +33,7 @@ def _extract_emission_value(value_iter: Any) -> Union[float, None]:
33
33
  value_list = list(value_iter)
34
34
  try:
35
35
  if len(list(value_list)) > 0 and len(list(value_list)[0]) > 1:
36
- return safe_parse_float(list(value_list)[0][1])
36
+ return safe_parse_float(list(value_list)[0][1], None)
37
37
  except ValueError:
38
38
  return None
39
39
 
@@ -1,7 +1,7 @@
1
1
  from hestia_earth.schema import TermTermType
2
2
  from hestia_earth.utils.model import filter_list_term_type
3
3
  from hestia_earth.utils.lookup import extract_grouped_data
4
- from hestia_earth.utils.tools import list_sum, safe_parse_float
4
+ from hestia_earth.utils.tools import list_sum, safe_parse_float, non_empty_list
5
5
 
6
6
  from hestia_earth.models.utils.completeness import _is_term_type_complete
7
7
  from hestia_earth.models.utils.term import get_lookup_value
@@ -19,14 +19,15 @@ def _get_fuel_input_value(term_id: str, lookup_col: str):
19
19
  get_lookup_value(operation_term, lookup_col, model=MODEL, term=term_id), input_term_id
20
20
  ) if operation_term else None
21
21
  input_factor = operation_factor or get_lookup_value(input_term, lookup_col, model=MODEL, term=term_id)
22
+ factor = safe_parse_float(input_factor, None)
22
23
 
23
- return input_value * safe_parse_float(input_factor)
24
+ return input_value * factor if factor is not None else None
24
25
  return get_value
25
26
 
26
27
 
27
28
  def get_fuel_values(term_id: str, cycle: dict, lookup_col: str):
28
29
  inputs = filter_list_term_type(cycle.get('inputs', []), TermTermType.FUEL)
29
- values = list(map(_get_fuel_input_value(term_id, lookup_col), inputs))
30
+ values = non_empty_list(map(_get_fuel_input_value(term_id, lookup_col), inputs))
30
31
 
31
32
  return [0] if all([
32
33
  len(values) == 0,
@@ -39,7 +39,7 @@ def _measurement(site: dict, value: float):
39
39
 
40
40
  def _download(site: dict):
41
41
  value = download(TERM_ID, site, EE_PARAMS)
42
- return 1 if value == 1 else (0 if value == 0.1 else None)
42
+ return value == 1
43
43
 
44
44
 
45
45
  def _run(site: dict):
@@ -189,7 +189,7 @@ def _calculate_GE(
189
189
  ) -> float:
190
190
  term_id = animal.get('term', {}).get('@id')
191
191
 
192
- NEm, NEa, NEl, NEwork, NEp, NEg = get_animal_values(cycle, animal, system)
192
+ NEm, NEa, NEl, NEwork, NEp, NEg = get_animal_values(cycle, animal, system, log_node=animal)
193
193
 
194
194
  NEm_feed, NEg_feed = calculate_NEfeed(animal)
195
195
  debugValues(animal, model=MODEL, term=term_id, model_key=MODEL_KEY,
@@ -205,19 +205,19 @@ def _calculate_GE(
205
205
  return (NEm + NEa + NEl + NEwork + NEp - NEm_feed)/REM + (NEg + NEwool - NEg_feed)/REG
206
206
 
207
207
 
208
- def _run_practice(cycle: dict, GE: float, meanECHHV: float):
208
+ def _run_practice(animal: dict, GE: float, meanECHHV: float):
209
209
  def run(practice: dict):
210
210
  key = practice.get('key', {})
211
211
  key_id = key.get('@id')
212
212
  input_term_id = practice_input_id(practice)
213
213
  value = (GE / meanECHHV) * (list_sum(practice.get('value', [0])) / 100)
214
214
 
215
- logRequirements(cycle, model=MODEL, term=input_term_id, model_key=MODEL_KEY,
215
+ logRequirements(animal, model=MODEL, term=input_term_id, model_key=MODEL_KEY,
216
216
  GE=GE,
217
217
  meanECHHV=meanECHHV,
218
- key_id=key_id)
218
+ practice_key_id=key_id)
219
219
 
220
- logShouldRun(cycle, MODEL, input_term_id, True, model_key=MODEL_KEY)
220
+ logShouldRun(animal, MODEL, input_term_id, True, model_key=MODEL_KEY)
221
221
 
222
222
  return _input(input_term_id, value)
223
223
 
@@ -249,7 +249,7 @@ def _run_animal(cycle: dict, meanDE: float, meanECHHV: float, system: dict, prac
249
249
  GE=GE,
250
250
  meanDE=meanDE)
251
251
 
252
- inputs = list(map(_run_practice(cycle, GE, meanECHHV), practices))
252
+ inputs = list(map(_run_practice(animal, GE, meanECHHV), practices))
253
253
  return animal | {
254
254
  'inputs': animal.get('inputs', []) + inputs
255
255
  }
@@ -7,7 +7,7 @@ from pydash.objects import merge
7
7
  from typing import NamedTuple, Optional, Union
8
8
 
9
9
  from hestia_earth.schema import (
10
- CycleFunctionalUnit, EmissionMethodTier, MeasurementMethodClassification
10
+ CycleFunctionalUnit, EmissionMethodTier, MeasurementMethodClassification, SiteSiteType
11
11
  )
12
12
  from hestia_earth.utils.date import diff_in_days
13
13
  from hestia_earth.utils.tools import flatten, non_empty_list, safe_parse_date
@@ -15,7 +15,8 @@ from hestia_earth.utils.tools import flatten, non_empty_list, safe_parse_date
15
15
  from hestia_earth.models.log import log_as_table, logRequirements, logShouldRun
16
16
  from hestia_earth.models.utils import pairwise
17
17
  from hestia_earth.models.utils.blank_node import (
18
- _get_datestr_format, _gapfill_datestr, DatestrGapfillMode, DatestrFormat, group_nodes_by_year, node_term_match
18
+ _get_datestr_format, _gapfill_datestr, DatestrGapfillMode, DatestrFormat, group_nodes_by_year, node_term_match,
19
+ cumulative_nodes_term_match
19
20
  )
20
21
  from hestia_earth.models.utils.constant import Units, get_atomic_conversion
21
22
  from hestia_earth.models.utils.emission import _new_emission, min_emission_method_tier
@@ -82,6 +83,13 @@ The list of `MeasurementMethodClassification`s that can be used to calculate SOC
82
83
  order from strongest to weakest.
83
84
  """
84
85
 
86
+ _SITE_TYPE_SYSTEMS_MAPPING = {
87
+ SiteSiteType.GLASS_OR_HIGH_ACCESSIBLE_COVER.value: [
88
+ "protectedCroppingSystemSoilBased",
89
+ "protectedCroppingSystemSoilAndSubstrateBased"
90
+ ]
91
+ }
92
+
85
93
 
86
94
  class _InventoryKey(Enum):
87
95
  """
@@ -207,19 +215,37 @@ def _should_run(cycle: dict) -> tuple[bool, str, dict]:
207
215
  soc_measurements = [node for node in site.get("measurements", []) if _validate_soc_measurement(node)]
208
216
  cycles = related_cycles(site)
209
217
 
218
+ site_type = site.get("siteType")
219
+ has_soil = site_type not in _SITE_TYPE_SYSTEMS_MAPPING or all(
220
+ cumulative_nodes_term_match(
221
+ cycle.get("practices", []),
222
+ target_term_ids=_SITE_TYPE_SYSTEMS_MAPPING[site_type],
223
+ cumulative_threshold=0
224
+ ) for cycle in cycles
225
+ )
226
+
210
227
  has_soc_measurements = len(soc_measurements) > 0
211
228
  has_cycles = len(cycles) > 0
212
229
  has_functional_unit_1_ha = all(cycle.get('functionalUnit') == CycleFunctionalUnit._1_HA.value for cycle in cycles)
213
230
 
214
- should_compile_inventory = all([has_cycles, has_functional_unit_1_ha, has_soc_measurements])
231
+ should_compile_inventory = all([
232
+ has_soil,
233
+ has_cycles,
234
+ has_functional_unit_1_ha,
235
+ has_soc_measurements,
236
+ ])
215
237
 
216
- inventory, logs = _compile_inventory(cycle_id, cycles, soc_measurements) if should_compile_inventory else ({}, {})
238
+ inventory, logs = (
239
+ _compile_inventory(cycle_id, cycles, soc_measurements) if should_compile_inventory else ({}, {})
240
+ )
217
241
 
218
242
  has_valid_inventory = len(inventory) > 0
219
243
  has_consecutive_years = check_consecutive(inventory.keys())
220
244
 
221
245
  logRequirements(
222
246
  cycle, model=MODEL, term=TERM_ID,
247
+ site_type=site_type,
248
+ has_soil=has_soil,
223
249
  has_soc_measurements=has_soc_measurements,
224
250
  has_cycles=has_cycles,
225
251
  has_functional_unit_1_ha=has_functional_unit_1_ha,
@@ -1,7 +1,8 @@
1
- from hestia_earth.schema import EmissionMethodTier
1
+ from hestia_earth.schema import EmissionMethodTier, TermTermType
2
2
 
3
3
  from hestia_earth.models.log import logRequirements, logShouldRun
4
4
  from hestia_earth.models.utils.constant import Units, get_atomic_conversion
5
+ from hestia_earth.models.utils.completeness import _is_term_type_complete
5
6
  from hestia_earth.models.utils.emission import _new_emission
6
7
  from hestia_earth.models.utils.input import total_excreta
7
8
  from hestia_earth.models.utils.excretaManagement import get_lookup_factor
@@ -9,6 +10,7 @@ from . import MODEL
9
10
 
10
11
  REQUIREMENTS = {
11
12
  "Cycle": {
13
+ "completeness.excreta": "True",
12
14
  "practices": [
13
15
  {"@type": "Practice", "value": "", "term.termType": "excretaManagement"}
14
16
  ]
@@ -42,10 +44,12 @@ def _run(excretaKgN: float, N2O_N_EF: float):
42
44
  def _should_run(cycle: dict):
43
45
  excretaKgN = total_excreta(cycle.get('inputs', []))
44
46
  N2O_N_EF = get_lookup_factor(cycle.get('practices', []), LOOKUPS['excretaManagement'])
47
+ term_type_complete = _is_term_type_complete(cycle, TermTermType.EXCRETA)
45
48
 
46
49
  logRequirements(cycle, model=MODEL, term=TERM_ID,
47
50
  excretaKgN=excretaKgN,
48
- N2O_N_EF=N2O_N_EF)
51
+ N2O_N_EF=N2O_N_EF,
52
+ term_type_excreta_complete=term_type_complete)
49
53
 
50
54
  should_run = all([excretaKgN, N2O_N_EF])
51
55
  logShouldRun(cycle, MODEL, TERM_ID, should_run, methodTier=TIER)
@@ -88,7 +88,7 @@ def _should_run(cycle: dict):
88
88
  no3_n=no3_n,
89
89
  nh3_n=nh3_n,
90
90
  nox_n=nox_n,
91
- term_type_cropResidue_complete=term_type_complete)
91
+ term_type_excreta_complete=term_type_complete)
92
92
 
93
93
  should_run = all([no3_n is not None, nh3_n is not None, nox_n is not None, term_type_complete])
94
94
  logShouldRun(cycle, MODEL, TERM_ID, should_run, methodTier=TIER)
@@ -97,7 +97,7 @@ def _should_run(cycle: dict):
97
97
  flooded_rice = has_flooded_rice(cycle.get('products', []))
98
98
 
99
99
  logRequirements(cycle, model=MODEL, term=TERM_ID,
100
- term_type_cropResidue_complete=term_type_complete,
100
+ term_type_fertiliser_complete=term_type_complete,
101
101
  N_total=N_total,
102
102
  has_flooded_rice=flooded_rice,
103
103
  ecoClimateZone=ecoClimateZone)
@@ -88,7 +88,7 @@ def _should_run(cycle: dict):
88
88
  no3_n=no3_n,
89
89
  nh3_n=nh3_n,
90
90
  nox_n=nox_n,
91
- term_type_cropResidue_complete=term_type_complete)
91
+ term_type_fertiliser_complete=term_type_complete)
92
92
 
93
93
  should_run = all([no3_n is not None, nh3_n is not None, nox_n is not None, term_type_complete])
94
94
  logShouldRun(cycle, MODEL, TERM_ID, should_run, methodTier=TIER)
@@ -88,7 +88,7 @@ def _should_run(cycle: dict):
88
88
  no3_n=no3_n,
89
89
  nh3_n=nh3_n,
90
90
  nox_n=nox_n,
91
- term_type_cropResidue_complete=term_type_complete)
91
+ term_type_fertiliser_complete=term_type_complete)
92
92
 
93
93
  should_run = all([no3_n is not None, nh3_n is not None, nox_n is not None, term_type_complete])
94
94
  logShouldRun(cycle, MODEL, TERM_ID, should_run, methodTier=TIER)
@@ -19,10 +19,11 @@ from typing import Callable, Optional, Union
19
19
 
20
20
  from hestia_earth.schema import MeasurementMethodClassification, SiteSiteType, TermTermType
21
21
  from hestia_earth.utils.model import find_term_match, filter_list_term_type
22
+ from hestia_earth.utils.blank_node import get_node_value
22
23
 
23
24
  from hestia_earth.models.utils.array_builders import gen_seed
24
25
  from hestia_earth.models.utils.blank_node import (
25
- cumulative_nodes_match, cumulative_nodes_lookup_match, cumulative_nodes_term_match, get_node_value,
26
+ cumulative_nodes_match, cumulative_nodes_lookup_match, cumulative_nodes_term_match,
26
27
  node_lookup_match, node_term_match, group_nodes_by_year
27
28
  )
28
29
  from hestia_earth.models.utils.descriptive_stats import calc_descriptive_stats
@@ -1952,6 +1953,7 @@ def _get_carbon_input_kwargs(
1952
1953
  crop_residue_management_nodes = filter_list_term_type(management_nodes, [TermTermType.CROPRESIDUEMANAGEMENT])
1953
1954
  land_cover_nodes = filter_list_term_type(management_nodes, [TermTermType.LANDCOVER])
1954
1955
  land_use_management_nodes = filter_list_term_type(management_nodes, [TermTermType.LANDUSEMANAGEMENT])
1956
+ system_nodes = filter_list_term_type(management_nodes, [TermTermType.SYSTEM])
1955
1957
  water_regime_nodes = filter_list_term_type(management_nodes, [TermTermType.WATERREGIME])
1956
1958
 
1957
1959
  has_animal_manure_used = any(
@@ -2006,7 +2008,7 @@ def _get_carbon_input_kwargs(
2006
2008
  node_lookup_match(node, PRACTICE_INCREASING_C_INPUT_LOOKUP, True)
2007
2009
  and not node_term_match(node, EXCLUDED_PRACTICE_TERM_IDS)
2008
2010
  ),
2009
- land_use_management_nodes,
2011
+ land_use_management_nodes + system_nodes,
2010
2012
  cumulative_threshold=MIN_AREA_THRESHOLD
2011
2013
  )
2012
2014
 
@@ -19,12 +19,13 @@ from hestia_earth.schema import (
19
19
  )
20
20
  from hestia_earth.utils.model import find_term_match, filter_list_term_type
21
21
  from hestia_earth.utils.tools import flatten, list_sum, non_empty_list
22
+ from hestia_earth.utils.blank_node import get_node_value
22
23
 
23
24
  from hestia_earth.models.utils.array_builders import (
24
25
  avg_run_in_columnwise, gen_seed, grouped_avg, repeat_1d_array_as_columns
25
26
  )
26
27
  from hestia_earth.models.utils.blank_node import (
27
- cumulative_nodes_lookup_match, cumulative_nodes_term_match, get_node_value, group_nodes_by_year,
28
+ cumulative_nodes_lookup_match, cumulative_nodes_term_match, group_nodes_by_year,
28
29
  group_nodes_by_year_and_month, GroupNodesByYearMode, node_term_match
29
30
  )
30
31
  from hestia_earth.models.utils.cycle import check_cycle_site_ids_identical
@@ -165,7 +165,7 @@ def calculate_NEwool(cycle: dict) -> float:
165
165
  def _calculate_GE(
166
166
  cycle: dict, animals: list, REM: float, REG: float, NEwool: float, NEm_feed: float, NEg_feed: float, system: dict
167
167
  ) -> float:
168
- values = [get_animal_values(cycle, animal, system) for animal in animals]
168
+ values = [get_animal_values(cycle, animal, system, log_node=cycle) for animal in animals]
169
169
  NEm = _sum_values(values, 0)
170
170
  NEa = _sum_values(values, 1)
171
171
  NEl = _sum_values(values, 2)
@@ -209,7 +209,7 @@ def _run_practice(cycle: dict, meanDE: float, meanECHHV: float, system: dict):
209
209
  NEm_feed=NEm_feed,
210
210
  NEg_feed=NEg_feed,
211
211
  GE=GE,
212
- key_id=key_id)
212
+ practice_key_id=key_id)
213
213
 
214
214
  logShouldRun(cycle, MODEL, input_term_id, True, model_key=MODEL_KEY)
215
215
 
@@ -242,7 +242,7 @@ def _should_run(cycle: dict, practices: dict):
242
242
  meanECHHV > 0
243
243
  ])
244
244
 
245
- for term_id in [MODEL_KEY] + [practice_input_id(p) for p in practices]:
245
+ for term_id in [practice_input_id(p) for p in practices] or [MODEL_KEY]:
246
246
  logRequirements(cycle, model=MODEL, term=term_id, model_key=MODEL_KEY,
247
247
  term_type_animalFeed_complete=animalFeed_complete,
248
248
  term_type_animalPopulation_complete=animalPopulation_complete,