hestia-earth-models 0.62.1__py3-none-any.whl → 0.62.3__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 (56) hide show
  1. hestia_earth/models/agribalyse2016/fuelElectricity.py +1 -1
  2. hestia_earth/models/cycle/animal/input/hestiaAggregatedData.py +1 -1
  3. hestia_earth/models/cycle/coldCarcassWeightPerHead.py +4 -2
  4. hestia_earth/models/cycle/coldDressedCarcassWeightPerHead.py +2 -2
  5. hestia_earth/models/cycle/concentrateFeed.py +3 -3
  6. hestia_earth/models/cycle/cycleDuration.py +7 -2
  7. hestia_earth/models/cycle/feedConversionRatio/feedConversionRatioNitrogen.py +2 -1
  8. hestia_earth/models/cycle/input/hestiaAggregatedData.py +1 -1
  9. hestia_earth/models/cycle/product/price.py +5 -1
  10. hestia_earth/models/cycle/product/revenue.py +6 -7
  11. hestia_earth/models/cycle/readyToCookWeightPerHead.py +2 -2
  12. hestia_earth/models/ecoinventV3/__init__.py +25 -52
  13. hestia_earth/models/ecoinventV3/utils.py +40 -0
  14. hestia_earth/models/ecoinventV3AndEmberClimate/__init__.py +92 -91
  15. hestia_earth/models/ecoinventV3AndEmberClimate/utils.py +15 -105
  16. hestia_earth/models/faostat2018/product/price.py +1 -2
  17. hestia_earth/models/geospatialDatabase/croppingIntensity.py +2 -1
  18. hestia_earth/models/geospatialDatabase/utils.py +1 -1
  19. hestia_earth/models/ipcc2019/aboveGroundCropResidueTotal.py +15 -10
  20. hestia_earth/models/ipcc2019/animal/pastureGrass.py +50 -40
  21. hestia_earth/models/ipcc2019/belowGroundCropResidue.py +16 -11
  22. hestia_earth/models/ipcc2019/carbonContent.py +1 -1
  23. hestia_earth/models/ipcc2019/croppingDuration.py +2 -2
  24. hestia_earth/models/ipcc2019/ligninContent.py +1 -1
  25. hestia_earth/models/ipcc2019/nitrogenContent.py +1 -1
  26. hestia_earth/models/ipcc2019/organicCarbonPerHa.py +3 -3
  27. hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_1_utils.py +5 -5
  28. hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_2_utils.py +217 -48
  29. hestia_earth/models/ipcc2019/organicCarbonPerHa_utils.py +2 -6
  30. hestia_earth/models/ipcc2019/pastureGrass.py +43 -41
  31. hestia_earth/models/ipcc2019/pastureGrass_utils.py +63 -109
  32. hestia_earth/models/koble2014/cropResidueManagement.py +1 -1
  33. hestia_earth/models/linkedImpactAssessment/emissions.py +15 -14
  34. hestia_earth/models/mocking/search-results.json +249 -257
  35. hestia_earth/models/pooreNemecek2018/longFallowPeriod.py +1 -1
  36. hestia_earth/models/preload_requests.py +1 -1
  37. hestia_earth/models/requirements.py +6 -6
  38. hestia_earth/models/site/organicCarbonPerHa.py +1 -1
  39. hestia_earth/models/utils/__init__.py +1 -1
  40. hestia_earth/models/utils/blank_node.py +52 -9
  41. hestia_earth/models/utils/cycle.py +12 -12
  42. hestia_earth/models/utils/measurement.py +3 -3
  43. hestia_earth/models/utils/property.py +6 -6
  44. hestia_earth/models/utils/term.py +2 -1
  45. hestia_earth/models/version.py +1 -1
  46. {hestia_earth_models-0.62.1.dist-info → hestia_earth_models-0.62.3.dist-info}/METADATA +12 -12
  47. {hestia_earth_models-0.62.1.dist-info → hestia_earth_models-0.62.3.dist-info}/RECORD +56 -55
  48. {hestia_earth_models-0.62.1.dist-info → hestia_earth_models-0.62.3.dist-info}/WHEEL +1 -1
  49. tests/models/cycle/product/test_revenue.py +0 -3
  50. tests/models/cycle/test_cycleDuration.py +1 -1
  51. tests/models/ipcc2019/test_organicCarbonPerHa.py +9 -20
  52. tests/models/ipcc2019/test_organicCarbonPerHa_tier_2_utils.py +0 -8
  53. tests/models/test_ecoinventV3.py +12 -0
  54. tests/models/test_ecoinventV3AndEmberClimate.py +5 -72
  55. {hestia_earth_models-0.62.1.dist-info → hestia_earth_models-0.62.3.dist-info}/LICENSE +0 -0
  56. {hestia_earth_models-0.62.1.dist-info → hestia_earth_models-0.62.3.dist-info}/top_level.txt +0 -0
@@ -1,116 +1,26 @@
1
- from typing import Dict, Any, Union, List
2
-
3
1
  from hestia_earth.utils.lookup import download_lookup, get_table_value, column_name, extract_grouped_data
4
- from hestia_earth.utils.tools import safe_parse_float, non_empty_list
2
+ from hestia_earth.utils.tools import safe_parse_float
5
3
 
6
4
  from hestia_earth.models.log import debugMissingLookup
7
- from hestia_earth.models.data.ecoinventV3 import ecoinventV3_emissions
8
-
5
+ from hestia_earth.models.utils.cycle import cycle_end_year
9
6
 
10
7
  EMBER_ECOINVENT_LOOKUP_NAME = "ember-ecoinvent-mapping.csv"
8
+ REGION_EMBER_SOURCES_LOOKUP_NAME = "region-ember-energySources.csv"
11
9
 
12
10
 
13
- def _lookup_data(term_id: str, grouping: str, country_id: str, year: str, lookup_name: str, **log_args):
14
- lookup = download_lookup(lookup_name)
15
- column = column_name(grouping)
16
- data = get_table_value(lookup, 'termid', country_id, column)
17
- percentage = extract_grouped_data(data, year)
18
- debugMissingLookup(lookup_name, 'termid', country_id, column, percentage, year=year, term=term_id, **log_args)
19
- return safe_parse_float(percentage, None)
20
-
21
-
22
- def _convert_name(name: str) -> str: return name.replace(";", ",")
23
-
24
-
25
- def _zero_from_non_numeric(value: Any) -> float:
26
- try:
27
- return float(value)
28
- except (ValueError, TypeError):
29
- return 0.0
30
-
31
-
32
- def _extract_emission_value(value_iter: Any) -> Union[float, None]:
33
- value_list = list(value_iter)
34
- try:
35
- if len(list(value_list)) > 0 and len(list(value_list)[0]) > 1:
36
- return safe_parse_float(list(value_list)[0][1], None)
37
- except ValueError:
38
- return None
39
-
40
-
41
- def _get_emission_rate_per_source(ember_ecoinvent_mapping: Dict, emission_term_id: str) -> Dict:
42
- """
43
- Returns the emissions rate in kg/kWh as a mapping indexed by ember energy source name.
44
- eg: {"bioenergy": 0.8947372128046288, "coal": 0.000124581084822, ... }
45
- """
11
+ def get_input_coefficient(model: str, cycle: dict, country_id: str, ecoinventName: str):
12
+ year = cycle_end_year(cycle)
46
13
 
47
- return {
48
- ember_source: _extract_emission_value(filter(
49
- lambda x: x[0] == emission_term_id,
50
- ecoinventV3_emissions(ecoinvent_lookup["ecoinventname"])
51
- ))
52
- for ember_source, ecoinvent_lookup in ember_ecoinvent_mapping.items()
53
- }
54
-
55
-
56
- def get_emission(term_id: str, country: str, year: int, energy: float, model: str) -> float:
57
- """
58
- Get the <term_id> emissions in kg for the energy consumed.
59
- a: ecoInventId of each source - from "ember-ecoinvent-mapping.csv"
60
- b: Ember sources list - from b
61
- c: Percentages per source - from region-ember-energySources.csv (country, ember-source, year:value)
62
- d: Energy per source (kWh) - from energy * each of c
63
- e: Emissions/kWh per source - from ecoinvent (using id from b)
64
- f: Emissions per source (kg) - from e * d for each source
65
- g: Total emissions - from sum(f)
66
- """
67
- # a: ecoInventId of each source
14
+ # find the matching ember source with the ecoinventName.
15
+ # example: "electricity, high voltage, electricity production, hard coal" > "Coal"
68
16
  ember_ecoinvent_lookup = download_lookup(EMBER_ECOINVENT_LOOKUP_NAME)
69
- ember_ecoinvent_mapping = {
70
- row["ember"].lower(): {"ecoinventid": row["ecoinventid"], "ecoinventname": _convert_name(row["ecoinventname"])}
71
- for row in ember_ecoinvent_lookup
72
- }
73
-
74
- # b: Ember sources
75
- ember_sources = list(ember_ecoinvent_mapping.keys())
76
-
77
- # c: Percentages per source
78
- percentages_per_source = {
79
- source: _lookup_data(
80
- term_id=source,
81
- grouping=source,
82
- country_id=country,
83
- year=str(year),
84
- lookup_name="region-ember-energySources.csv",
85
- model=model
86
- )
87
- for source in ember_sources
88
- }
89
-
90
- # d: Energy per source (kWh)
91
- energy_per_source = {
92
- source: energy * _zero_from_non_numeric(percentage) / 100
93
- for source, percentage in percentages_per_source.items()
94
- }
17
+ source_name = get_table_value(ember_ecoinvent_lookup, column_name('ecoinventName'), ecoinventName, 'ember')
95
18
 
96
- # e: Emissions/kWh per source
97
- emission_rate_per_source = _get_emission_rate_per_source(
98
- ember_ecoinvent_mapping=ember_ecoinvent_mapping,
99
- emission_term_id=term_id
100
- )
19
+ # find the ratio for the country / year
20
+ region_ember_sources_lookup = download_lookup(REGION_EMBER_SOURCES_LOOKUP_NAME)
21
+ data = get_table_value(region_ember_sources_lookup, 'termid', country_id, column_name(source_name))
22
+ percentage = extract_grouped_data(data, str(year))
23
+ debugMissingLookup(REGION_EMBER_SOURCES_LOOKUP_NAME,
24
+ 'termid', country_id, source_name, percentage, year=year, model=model)
101
25
 
102
- # f: Emissions per source (kg)
103
- emissions_per_source = {
104
- source: energy_per_source[source] * emission_rate_per_source[source]
105
- for source in ember_sources
106
- if energy_per_source[source] is not None and emission_rate_per_source[source] is not None
107
- }
108
-
109
- # g: Total emissions (kg of <term_id>)
110
- return sum(emissions_per_source.values())
111
-
112
-
113
- def get_all_emission_terms() -> List[str]:
114
- ember_ecoinvent_lookup = download_lookup(EMBER_ECOINVENT_LOOKUP_NAME)
115
- eco_invent_name = _convert_name(ember_ecoinvent_lookup[0]["ecoinventname"])
116
- return [e[0] for e in non_empty_list(ecoinventV3_emissions(eco_invent_name))]
26
+ return safe_parse_float(percentage, 0) / 100
@@ -157,8 +157,7 @@ def _run_by_country(cycle: dict, product: dict, country_id: str, year: int = Non
157
157
  return _product(product, value / 1000 * conversion_to_number) if value is not None else None
158
158
 
159
159
 
160
- def _should_run_product(product: dict):
161
- return product.get(MODEL_KEY) is None
160
+ def _should_run_product(product: dict): return product.get(MODEL_KEY) is None
162
161
 
163
162
 
164
163
  def run(cycle: dict):
@@ -37,7 +37,8 @@ TERM_ID = 'croppingIntensity'
37
37
 
38
38
  def _practice(value: float):
39
39
  practice = _new_practice(TERM_ID)
40
- practice['value'] = [round(value, 7)]
40
+ # force conversion to float from numpy, avoiding errors when reading it in other models
41
+ practice['value'] = [float(round(value, 7))]
41
42
  return practice
42
43
 
43
44
 
@@ -152,7 +152,7 @@ def _get_cached_data(term: str, site: dict, data: dict):
152
152
 
153
153
  def download(term: str, site: dict, data: dict, only_coordinates=False) -> dict:
154
154
  """
155
- Downloads data from Hestia Earth Engine API.
155
+ Downloads data from HESTIA Earth Engine API.
156
156
 
157
157
  Returns
158
158
  -------
@@ -2,7 +2,7 @@ from hestia_earth.schema import TermTermType
2
2
  from hestia_earth.utils.model import filter_list_term_type
3
3
  from hestia_earth.utils.tools import list_sum
4
4
 
5
- from hestia_earth.models.log import debugValues, logRequirements, logShouldRun
5
+ from hestia_earth.models.log import debugValues, logRequirements, logShouldRun, log_as_table
6
6
  from hestia_earth.models.utils.completeness import _is_term_type_incomplete
7
7
  from hestia_earth.models.utils.product import _new_product
8
8
  from hestia_earth.models.utils.property import get_node_property
@@ -46,16 +46,21 @@ def _product_value(product: dict):
46
46
  value = list_sum(product.get('value'))
47
47
  dm = get_node_property(product, PROPERTY_KEY).get('value', 0)
48
48
  yield_dm = get_yield_dm(TERM_ID, term) or 0
49
- debugValues(product, model=MODEL, term=TERM_ID,
50
- product=term_id,
51
- value=value,
52
- dryMatter=dm,
53
- ratio_yield_dm=yield_dm)
54
- return value * dm / 100 * yield_dm
49
+ total = value * dm / 100 * yield_dm
50
+ return {
51
+ 'id': term_id,
52
+ 'value': value,
53
+ 'dryMatter': dm,
54
+ 'RatioYieldDM': yield_dm,
55
+ 'total': total
56
+ }
55
57
 
56
58
 
57
- def _run(products: list):
58
- value = sum(map(_product_value, products))
59
+ def _run(cycle: dict, products: list):
60
+ values = list(map(_product_value, products))
61
+ debugValues(cycle, model=MODEL, term=TERM_ID,
62
+ details=log_as_table(values))
63
+ value = sum([value.get('total', 0) for value in values])
59
64
  return [_product(value)]
60
65
 
61
66
 
@@ -85,4 +90,4 @@ def _should_run(cycle: dict):
85
90
 
86
91
  def run(cycle: dict):
87
92
  should_run, products = _should_run(cycle)
88
- return _run(products) if should_run else []
93
+ return _run(cycle, products) if should_run else []
@@ -12,7 +12,8 @@ from hestia_earth.schema import TermTermType
12
12
  from hestia_earth.utils.model import filter_list_term_type
13
13
  from hestia_earth.utils.tools import list_sum
14
14
 
15
- from hestia_earth.models.log import logRequirements, logShouldRun, debugValues
15
+ from hestia_earth.models.log import logRequirements, logShouldRun, debugValues, log_as_table
16
+ from hestia_earth.models.utils.blank_node import lookups_logs, properties_logs
16
17
  from hestia_earth.models.utils.input import _new_input
17
18
  from hestia_earth.models.utils.term import get_wool_terms, get_lookup_value
18
19
  from hestia_earth.models.utils.completeness import _is_term_type_complete, _is_term_type_incomplete
@@ -26,6 +27,7 @@ from ..pastureGrass_utils import (
26
27
  calculate_REM,
27
28
  calculate_REG,
28
29
  calculate_NEfeed,
30
+ calculate_GE,
29
31
  product_wool_energy,
30
32
  get_animals,
31
33
  get_animal_values
@@ -115,7 +117,8 @@ REQUIREMENTS = {
115
117
  }
116
118
  LOOKUPS = {
117
119
  "animalManagement": [
118
- "mjKgEvMilkIpcc2019"
120
+ "mjKgEvMilkIpcc2019",
121
+ "defaultFatContentEvMilkIpcc2019"
119
122
  ],
120
123
  "animalProduct": ["mjKgEvWoolNetEnergyWoolIpcc2019", "allowedLiveAnimalTermIds"],
121
124
  "liveAnimal": [
@@ -184,38 +187,50 @@ def calculate_NEwool(cycle: dict, animal: dict, products: list, total_weight: fl
184
187
  return total_energy * animal_weight/total_weight
185
188
 
186
189
 
187
- def _calculate_GE(
188
- cycle: dict, animal: dict, REM: float, REG: float, NEwool: float, system: dict
189
- ) -> float:
190
- term_id = animal.get('term', {}).get('@id')
191
-
192
- NEm, NEa, NEl, NEwork, NEp, NEg = get_animal_values(cycle, animal, system, log_node=animal)
193
-
194
- NEm_feed, NEg_feed = calculate_NEfeed(animal)
195
- debugValues(animal, model=MODEL, term=term_id, model_key=MODEL_KEY,
196
- NEm=NEm,
197
- NEa=NEa,
198
- NEl=NEl,
199
- NEwork=NEwork,
200
- NEp=NEp,
201
- NEg=NEg,
202
- NEm_feed=NEm_feed,
203
- NEg_feed=NEg_feed)
204
-
205
- return (NEm + NEa + NEl + NEwork + NEp - NEm_feed)/REM + (NEg + NEwool - NEg_feed)/REG
206
-
207
-
208
- def _run_practice(animal: dict, GE: float, meanECHHV: float):
190
+ def _run_practice(
191
+ animal: dict, values: dict, meanDE: float, meanECHHV: float, REM: float, REG: float,
192
+ NEwool: float, NEm_feed: float, NEg_feed: float
193
+ ):
209
194
  def run(practice: dict):
210
195
  key = practice.get('key', {})
211
196
  key_id = key.get('@id')
212
197
  input_term_id = practice_input_id(practice)
198
+
199
+ GE = (
200
+ calculate_GE([values], REM, REG, NEwool, NEm_feed, NEg_feed) / (meanDE/100)
201
+ ) if meanDE else 0
202
+
213
203
  value = (GE / meanECHHV) * (list_sum(practice.get('value', [0])) / 100)
214
204
 
205
+ logs = log_as_table(values | {
206
+ 'animalId': animal.get('term', {}).get('@id'),
207
+ 'practiceKeyId': key_id,
208
+ 'GE': GE,
209
+ 'NEmFeed': NEm_feed,
210
+ 'NEgFeed': NEg_feed,
211
+ 'REM': REM,
212
+ 'REG': REG,
213
+ 'NEwool': NEwool,
214
+ 'meanECHHV': meanECHHV,
215
+ 'meanDE': meanDE
216
+ })
217
+ animal_lookups = lookups_logs(MODEL, [animal], LOOKUPS, model_key=MODEL_KEY, term=input_term_id)
218
+ animal_properties = properties_logs([animal], properties=[
219
+ 'liveweightPerHead',
220
+ 'hoursWorkedPerDay',
221
+ 'animalsPerBirth',
222
+ 'pregnancyRateTotal',
223
+ 'weightAtMaturity',
224
+ 'liveweightGain',
225
+ 'weightAtWeaning',
226
+ 'weightAtOneYear',
227
+ 'weightAtSlaughter'
228
+ ])
229
+
215
230
  logRequirements(animal, model=MODEL, term=input_term_id, model_key=MODEL_KEY,
216
- GE=GE,
217
- meanECHHV=meanECHHV,
218
- practice_key_id=key_id)
231
+ animal_logs=logs,
232
+ animal_lookups=animal_lookups,
233
+ animal_properties=animal_properties)
219
234
 
220
235
  logShouldRun(animal, MODEL, input_term_id, True, model_key=MODEL_KEY)
221
236
 
@@ -235,21 +250,16 @@ def _run_animal(cycle: dict, meanDE: float, meanECHHV: float, system: dict, prac
235
250
  total_liveWeightPerHead = _sum_liveWeightPerHead(animals)
236
251
 
237
252
  def run(animal: dict):
238
- term_id = animal.get('term', {}).get('@id')
239
-
240
253
  NEwool = calculate_NEwool(cycle, animal, wool_products, total_liveWeightPerHead) if (
241
254
  total_liveWeightPerHead > 0
242
255
  ) else 0
243
- GE = (_calculate_GE(cycle, animal, REM, REG, NEwool, system) / (meanDE/100)) if all([REM, REG]) else 0
244
-
245
- debugValues(animal, model=MODEL, term=term_id, model_key=MODEL_KEY,
246
- REM=REM,
247
- REG=REG,
248
- NEwool=NEwool,
249
- GE=GE,
250
- meanDE=meanDE)
256
+ NEm_feed, NEg_feed = calculate_NEfeed(animal)
257
+ animal_values = get_animal_values(cycle, animal, system)
251
258
 
252
- inputs = list(map(_run_practice(animal, GE, meanECHHV), practices))
259
+ inputs = list(map(
260
+ _run_practice(animal, animal_values, meanDE, meanECHHV, REM, REG, NEwool, NEm_feed, NEg_feed),
261
+ practices
262
+ ))
253
263
  return animal | {
254
264
  'inputs': animal.get('inputs', []) + inputs
255
265
  }
@@ -289,8 +299,8 @@ def _should_run(cycle: dict, animals: list, practices: dict):
289
299
  term_type_freshForage_incomplete=freshForage_incomplete,
290
300
  no_cycle_inputs_feed=no_cycle_inputs_feed,
291
301
  all_animals_have_value=all_animals_have_value,
292
- meanDE=meanDE,
293
- meanECHHV=meanECHHV)
302
+ meanDE=calculate_meanDE(practices, term=term_id),
303
+ meanECHHV=calculate_meanECHHV(practices, term=term_id))
294
304
 
295
305
  logShouldRun(animal, MODEL, term_id, should_run, model_key=MODEL_KEY)
296
306
 
@@ -2,7 +2,7 @@ from hestia_earth.schema import TermTermType
2
2
  from hestia_earth.utils.model import filter_list_term_type
3
3
  from hestia_earth.utils.tools import list_sum, safe_parse_float
4
4
 
5
- from hestia_earth.models.log import debugValues, logRequirements, logShouldRun
5
+ from hestia_earth.models.log import debugValues, logRequirements, logShouldRun, log_as_table
6
6
  from hestia_earth.models.utils.completeness import _is_term_type_incomplete
7
7
  from hestia_earth.models.utils.product import _new_product
8
8
  from hestia_earth.models.utils.property import get_node_property
@@ -52,17 +52,22 @@ def _product_value(product: dict):
52
52
  dm = get_node_property(product, PROPERTY_KEY).get('value', 0)
53
53
  yield_dm = get_yield_dm(TERM_ID, term) or 0
54
54
  ratio = _get_lookup_value(term, 'IPCC_2019_Ratio_BGRes_AGRes') or 0
55
- debugValues(product, model=MODEL, term=TERM_ID,
56
- product=term_id,
57
- value=value,
58
- dryMatter=dm,
59
- ratio_yield_dm=yield_dm,
60
- ratio=ratio)
61
- return value * dm / 100 * yield_dm * ratio
55
+ total = value * dm / 100 * yield_dm * ratio
56
+ return {
57
+ 'id': term_id,
58
+ 'value': value,
59
+ 'dryMatter': dm,
60
+ 'RatioYieldDM': yield_dm,
61
+ 'RatioAboveGroundToBelowGround': ratio,
62
+ 'total': total
63
+ }
62
64
 
63
65
 
64
- def _run(products: list):
65
- value = sum(map(_product_value, products))
66
+ def _run(cycle: dict, products: list):
67
+ values = list(map(_product_value, products))
68
+ debugValues(cycle, model=MODEL, term=TERM_ID,
69
+ details=log_as_table(values))
70
+ value = sum([value.get('total', 0) for value in values])
66
71
  return [_product(value)]
67
72
 
68
73
 
@@ -92,4 +97,4 @@ def _should_run(cycle: dict):
92
97
 
93
98
  def run(cycle: dict):
94
99
  should_run, products = _should_run(cycle)
95
- return _run(products) if should_run else []
100
+ return _run(cycle, products) if should_run else []
@@ -114,7 +114,7 @@ def _multiple_product_values(crop: dict, residue_id: str):
114
114
  # LIGNIN_CONTENT_AG_CROP_RESIDUE or LIGNIN_CONTENT_BG_CROP_RESIDUE
115
115
  c_content = _get_lookup_value(term, _crop_residue_lookup_col(residue_id))
116
116
  ratio = _get_lookup_value(term, 'IPCC_2019_Ratio_BGRes_AGRes') if residue_id == 'belowGroundCropResidue' else 1
117
- debugValues(crop, model=MODEL, term=residue_id,
117
+ debugValues(crop, model=MODEL, term=residue_id, property=TERM_ID,
118
118
  crop=term_id,
119
119
  dryMatter=dm,
120
120
  ratio_yield_dm=yield_dm,
@@ -80,11 +80,11 @@ def _should_run(cycle: dict):
80
80
  logRequirements(cycle, model=MODEL, term=TERM_ID,
81
81
  country=country,
82
82
  has_flooded_rice=flooded_rice,
83
- cycleDuration=cycleDuration,
83
+ cycleDuration=cycle.get('cycleDuration'),
84
84
  croppingDuration=croppingDuration,
85
85
  croppingDuration_below_cycleDuration=croppingDuration_below_cycleDuration)
86
86
 
87
- should_run = all([country, cycleDuration, flooded_rice])
87
+ should_run = all([country, cycleDuration > 0, croppingDuration_below_cycleDuration, flooded_rice])
88
88
  logShouldRun(cycle, MODEL, TERM_ID, should_run)
89
89
  return should_run, country
90
90
 
@@ -114,7 +114,7 @@ def _multiple_product_values(crop: dict, residue_id: str):
114
114
  # LIGNIN_CONTENT_AG_CROP_RESIDUE or LIGNIN_CONTENT_BG_CROP_RESIDUE
115
115
  l_content = _get_lookup_value(term, _crop_residue_lookup_col(residue_id))
116
116
  ratio = _get_lookup_value(term, 'IPCC_2019_Ratio_BGRes_AGRes') if residue_id == 'belowGroundCropResidue' else 1
117
- debugValues(crop, model=MODEL, term=residue_id,
117
+ debugValues(crop, model=MODEL, term=residue_id, property=TERM_ID,
118
118
  crop=term_id,
119
119
  dryMatter=dm,
120
120
  ratio_yield_dm=yield_dm,
@@ -114,7 +114,7 @@ def _multiple_product_value(crop: dict, residue_id: str):
114
114
  # N_Content_AG_Residue or N_Content_BG_Residue
115
115
  n_content = _get_lookup_value(term, _crop_residue_lookup_col(residue_id))
116
116
  ratio = _get_lookup_value(term, 'IPCC_2019_Ratio_BGRes_AGRes') if residue_id == 'belowGroundCropResidue' else 1
117
- debugValues(crop, model=MODEL, term=residue_id,
117
+ debugValues(crop, model=MODEL, term=residue_id, property=TERM_ID,
118
118
  crop=term_id,
119
119
  dryMatter=dm,
120
120
  ratio_yield_dm=yield_dm,
@@ -8,7 +8,7 @@ Both tier methodologies are run as Monte Carlo simulations with 10000 iterations
8
8
 
9
9
  The requirements in this file are for the Tier 1 methodology only, as it has simpler requirements. The requirements for
10
10
  the Tier 2 methodology can be found in the
11
- [Hestia SOC wiki](https://gitlab.com/hestia-earth/hestia-engine-models/-/wikis/Soil-organic-carbon-modelling)
11
+ [HESTIA SOC wiki](https://gitlab.com/hestia-earth/hestia-engine-models/-/wikis/Soil-organic-carbon-modelling)
12
12
  alongside data recommendations, examples and explanations for both tiers.
13
13
  """
14
14
  from functools import reduce
@@ -130,12 +130,12 @@ def run(site: dict) -> list[dict]:
130
130
  Parameters
131
131
  ----------
132
132
  site : dict
133
- A Hestia `Site` node, see: https://www.hestia.earth/schema/Site.
133
+ A HESTIA `Site` node, see: https://www.hestia.earth/schema/Site.
134
134
 
135
135
  Returns
136
136
  -------
137
137
  list[dict]
138
- A list of Hestia `Measurement` nodes containing the calculated SOC stocks and additional relevant data.
138
+ A list of HESTIA `Measurement` nodes containing the calculated SOC stocks and additional relevant data.
139
139
  """
140
140
  should_run, run_data = _should_run(site)
141
141
  _log_data(site, should_run, run_data)
@@ -5,7 +5,7 @@ management changes.
5
5
  The model cannot not run on Sites with polar moist (ecoClimateZone 5) or polar dry (ecoClimateZone 6).
6
6
 
7
7
  More information on this model, including data requirements **and** recommendations, and examples can be found in the
8
- [Hestia SOC wiki](https://gitlab.com/hestia-earth/hestia-engine-models/-/wikis/Soil-organic-carbon-modelling).
8
+ [HESTIA SOC wiki](https://gitlab.com/hestia-earth/hestia-engine-models/-/wikis/Soil-organic-carbon-modelling).
9
9
 
10
10
  Source: [IPCC 2019, Vol. 4, Chapter 2](https://www.ipcc-nggip.iges.or.jp/public/2019rf/vol4.html).
11
11
  """
@@ -92,7 +92,7 @@ def _measurement(
92
92
  descriptive_stats_dict: dict
93
93
  ) -> dict:
94
94
  """
95
- Build a Hestia `Measurement` node to contain a value and descriptive statistics calculated by the models.
95
+ Build a HESTIA `Measurement` node to contain a value and descriptive statistics calculated by the models.
96
96
 
97
97
  The `descriptive_stats_dict` parameter should include the following keys and values from the
98
98
  [Measurement](https://www-staging.hestia.earth/schema/Measurement) schema:
@@ -117,7 +117,7 @@ def _measurement(
117
117
  Returns
118
118
  -------
119
119
  dict
120
- A valid Hestia `Measurement` node, see: https://www.hestia.earth/schema/Measurement.
120
+ A valid HESTIA `Measurement` node, see: https://www.hestia.earth/schema/Measurement.
121
121
  """
122
122
  measurement = _new_measurement(_TERM_ID) | descriptive_stats_dict
123
123
  measurement["dates"] = [f"{year}-12-31" for year in timestamps]
@@ -640,7 +640,7 @@ def should_run(site: dict) -> tuple[bool, dict, dict]:
640
640
  Parameters
641
641
  ----------
642
642
  site : dict
643
- A Hestia `Site` node, see: https://www.hestia.earth/schema/Site.
643
+ A HESTIA `Site` node, see: https://www.hestia.earth/schema/Site.
644
644
 
645
645
  Returns
646
646
  -------
@@ -694,7 +694,7 @@ def run(
694
694
  ) -> list[dict]:
695
695
  """
696
696
  Run the IPCC (2019) Tier 1 methodology for calculating SOC stocks (in kg C ha-1) for each year in the inventory
697
- and wrap each of the calculated values in Hestia measurement nodes. To avoid any errors, the `inventory` parameter
697
+ and wrap each of the calculated values in HESTIA measurement nodes. To avoid any errors, the `inventory` parameter
698
698
  must be pre-validated by the `should_run` function.
699
699
 
700
700
  See [IPCC (2019) Vol. 4, Ch. 2](https://www.ipcc-nggip.iges.or.jp/public/2019rf/vol4.html) for more information.