hestia-earth-models 0.65.3__py3-none-any.whl → 0.65.5__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 (59) hide show
  1. hestia_earth/models/agribalyse2016/fuelElectricity.py +41 -35
  2. hestia_earth/models/aware/scarcityWeightedWaterUse.py +1 -1
  3. hestia_earth/models/cache_sites.py +2 -0
  4. hestia_earth/models/chaudharyBrooks2018/damageToTerrestrialEcosystemsLandOccupation.py +1 -1
  5. hestia_earth/models/chaudharyBrooks2018/damageToTerrestrialEcosystemsLandTransformation.py +1 -1
  6. hestia_earth/models/chaudharyBrooks2018/damageToTerrestrialEcosystemsTotalLandUseEffects.py +1 -1
  7. hestia_earth/models/cycle/completeness/__init__.py +1 -1
  8. hestia_earth/models/cycle/completeness/electricityFuel.py +4 -2
  9. hestia_earth/models/emepEea2019/nh3ToAirInorganicFertiliser.py +1 -1
  10. hestia_earth/models/geospatialDatabase/precipitationAnnual.py +2 -2
  11. hestia_earth/models/geospatialDatabase/precipitationLongTermAnnualMean.py +2 -2
  12. hestia_earth/models/geospatialDatabase/precipitationMonthly.py +2 -2
  13. hestia_earth/models/geospatialDatabase/temperatureAnnual.py +2 -2
  14. hestia_earth/models/geospatialDatabase/temperatureLongTermAnnualMean.py +2 -2
  15. hestia_earth/models/geospatialDatabase/temperatureMonthly.py +2 -2
  16. hestia_earth/models/hestia/landCover.py +31 -46
  17. hestia_earth/models/hestia/landTransformation100YearAverageDuringCycle.py +49 -0
  18. hestia_earth/models/hestia/landTransformation20YearAverageDuringCycle.py +49 -0
  19. hestia_earth/models/hestia/resourceUse_utils.py +200 -0
  20. hestia_earth/models/hestia/seed_emissions.py +37 -28
  21. hestia_earth/models/hestia/utils.py +48 -0
  22. hestia_earth/models/impact_assessment/emissions.py +20 -5
  23. hestia_earth/models/ipcc2019/co2ToAirCarbonStockChange_utils.py +66 -28
  24. hestia_earth/models/ipcc2019/croppingDuration.py +5 -0
  25. hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_1_utils.py +26 -142
  26. hestia_earth/models/ipcc2019/organicCarbonPerHa_tier_2_utils.py +3 -3
  27. hestia_earth/models/ipcc2019/organicCarbonPerHa_utils.py +8 -5
  28. hestia_earth/models/linkedImpactAssessment/freshwaterWithdrawalsInputsProduction.py +2 -1
  29. hestia_earth/models/linkedImpactAssessment/landOccupationInputsProduction.py +1 -0
  30. hestia_earth/models/linkedImpactAssessment/landTransformation100YearAverageInputsProduction.py +1 -0
  31. hestia_earth/models/linkedImpactAssessment/landTransformation20YearAverageInputsProduction.py +1 -0
  32. hestia_earth/models/linkedImpactAssessment/utils.py +25 -20
  33. hestia_earth/models/mocking/search-results.json +670 -654
  34. hestia_earth/models/pooreNemecek2018/freshwaterWithdrawalsDuringCycle.py +4 -1
  35. hestia_earth/models/schererPfister2015/nErosionSoilFlux.py +23 -14
  36. hestia_earth/models/schererPfister2015/pErosionSoilFlux.py +23 -15
  37. hestia_earth/models/schererPfister2015/utils.py +3 -5
  38. hestia_earth/models/site/management.py +2 -2
  39. hestia_earth/models/utils/__init__.py +9 -0
  40. hestia_earth/models/utils/blank_node.py +28 -0
  41. hestia_earth/models/utils/ecoClimateZone.py +1 -4
  42. hestia_earth/models/utils/fuel.py +4 -1
  43. hestia_earth/models/utils/impact_assessment.py +7 -5
  44. hestia_earth/models/utils/lookup.py +8 -2
  45. hestia_earth/models/utils/pesticideAI.py +1 -0
  46. hestia_earth/models/version.py +1 -1
  47. {hestia_earth_models-0.65.3.dist-info → hestia_earth_models-0.65.5.dist-info}/METADATA +2 -2
  48. {hestia_earth_models-0.65.3.dist-info → hestia_earth_models-0.65.5.dist-info}/RECORD +59 -53
  49. tests/models/hestia/test_landTransformation100YearAverageDuringCycle.py +30 -0
  50. tests/models/hestia/test_landTransformation20YearAverageDuringCycle.py +31 -0
  51. tests/models/ipcc2019/test_co2ToAirAboveGroundBiomassStockChange.py +3 -1
  52. tests/models/ipcc2019/test_co2ToAirBelowGroundBiomassStockChange.py +3 -1
  53. tests/models/ipcc2019/test_co2ToAirSoilOrganicCarbonStockChange.py +3 -1
  54. tests/models/ipcc2019/test_organicCarbonPerHa.py +3 -2
  55. tests/models/ipcc2019/test_organicCarbonPerHa_tier_1_utils.py +15 -11
  56. tests/models/utils/test_blank_node.py +22 -7
  57. {hestia_earth_models-0.65.3.dist-info → hestia_earth_models-0.65.5.dist-info}/LICENSE +0 -0
  58. {hestia_earth_models-0.65.3.dist-info → hestia_earth_models-0.65.5.dist-info}/WHEEL +0 -0
  59. {hestia_earth_models-0.65.3.dist-info → hestia_earth_models-0.65.5.dist-info}/top_level.txt +0 -0
@@ -47,7 +47,6 @@ _NOMINAL_ERROR = 75
47
47
  Carbon stock measurements without an associated `sd` should be assigned a nominal error of 75% (2*sd as a percentage of
48
48
  the mean).
49
49
  """
50
- _DEFAULT_YEARS_SINCE_LUC_EVENT = 999
51
50
  _TRANSITION_PERIOD_YEARS = 20
52
51
  _TRANSITION_PERIOD_DAYS = 20 * YEAR # 20 years in days
53
52
  _VALID_DATE_FORMATS = {
@@ -96,6 +95,7 @@ class _InventoryKey(Enum):
96
95
  LAND_USE_SUMMARY = "land-use-summary"
97
96
  LAND_USE_CHANGE_EVENT = "luc-event"
98
97
  YEARS_SINCE_LUC_EVENT = "years-since-luc-event"
98
+ YEARS_SINCE_INVENTORY_START = "years-since-inventory-start"
99
99
 
100
100
 
101
101
  CarbonStock = NamedTuple("CarbonStock", [
@@ -611,7 +611,6 @@ def _create_compile_inventory_function(
611
611
  )
612
612
 
613
613
  inventory = _squash_inventory(
614
- cycle_id,
615
614
  cycle_inventory,
616
615
  carbon_stock_inventory,
617
616
  land_use_inventory,
@@ -1008,14 +1007,20 @@ def _compile_land_use_inventory(
1008
1007
  is_luc_event = detect_land_use_change_func(land_use_summary, prev_land_use_summary)
1009
1008
 
1010
1009
  time_delta = current_year - prev_year
1011
- prev_years_since_luc_event = result.get(prev_year, {}).get(_InventoryKey.YEARS_SINCE_LUC_EVENT, 0)
1010
+ prev_years_since_luc_event = (
1011
+ result.get(prev_year, {}).get(_InventoryKey.YEARS_SINCE_LUC_EVENT, _TRANSITION_PERIOD_YEARS)
1012
+ )
1013
+ prev_years_since_inventory_start = result.get(prev_year, {}).get(_InventoryKey.YEARS_SINCE_INVENTORY_START, 0)
1014
+
1012
1015
  years_since_luc_event = time_delta if is_luc_event else prev_years_since_luc_event + time_delta
1016
+ years_since_inventory_start = prev_years_since_inventory_start + time_delta
1013
1017
 
1014
1018
  update_dict = {
1015
1019
  current_year: {
1016
1020
  _InventoryKey.LAND_USE_SUMMARY: land_use_summary,
1017
1021
  _InventoryKey.LAND_USE_CHANGE_EVENT: is_luc_event,
1018
1022
  _InventoryKey.YEARS_SINCE_LUC_EVENT: years_since_luc_event,
1023
+ _InventoryKey.YEARS_SINCE_INVENTORY_START: years_since_inventory_start
1019
1024
  }
1020
1025
  }
1021
1026
  return result | update_dict
@@ -1030,9 +1035,7 @@ def _compile_land_use_inventory(
1030
1035
  start_year: {
1031
1036
  _InventoryKey.LAND_USE_SUMMARY: summarise_land_use_func(
1032
1037
  land_cover_nodes_by_year.get(start_year, [])
1033
- ),
1034
- _InventoryKey.LAND_USE_CHANGE_EVENT: False,
1035
- _InventoryKey.YEARS_SINCE_LUC_EVENT: _DEFAULT_YEARS_SINCE_LUC_EVENT
1038
+ )
1036
1039
  }
1037
1040
  }
1038
1041
  ) if should_run else {}
@@ -1062,7 +1065,6 @@ def _sorted_merge(*sources: Union[dict, list[dict]]) -> dict:
1062
1065
 
1063
1066
 
1064
1067
  def _squash_inventory(
1065
- cycle_id: str,
1066
1068
  cycle_inventory: dict,
1067
1069
  carbon_stock_inventory: dict,
1068
1070
  land_use_inventory: dict,
@@ -1075,8 +1077,6 @@ def _squash_inventory(
1075
1077
 
1076
1078
  Parameters
1077
1079
  ----------
1078
- cycle_id : str
1079
- The unique identifier of the cycle being processed.
1080
1080
 
1081
1081
  cycle_inventory : dict
1082
1082
  A dictionary representing the share of emissions for each cycle, grouped by year.
@@ -1162,12 +1162,7 @@ def _squash_inventory(
1162
1162
  )))
1163
1163
 
1164
1164
  def should_run_group(method: MeasurementMethodClassification, year: int) -> bool:
1165
- carbon_stock_inventory_group = carbon_stock_inventory.get(method, {}).get(year, {})
1166
- share_of_emissions_group = cycle_inventory.get(year, {})
1167
-
1168
- has_emission = _InventoryKey.CO2_EMISSION in carbon_stock_inventory_group.keys()
1169
- is_relevant_for_cycle = cycle_id in share_of_emissions_group.get(_InventoryKey.SHARE_OF_EMISSION, {}).keys()
1170
- return all([has_emission, is_relevant_for_cycle])
1165
+ return _InventoryKey.CO2_EMISSION in carbon_stock_inventory.get(method, {}).get(year, {}).keys()
1171
1166
 
1172
1167
  def squash(result: dict, year: int) -> dict:
1173
1168
  update_dict = next(
@@ -1175,7 +1170,10 @@ def _squash_inventory(
1175
1170
  {
1176
1171
  year: {
1177
1172
  **_get_land_use_change_data(year, land_use_inventory),
1178
- **reduce(merge, [carbon_stock_inventory[method][year], cycle_inventory[year]], dict())
1173
+ **reduce(merge, [
1174
+ carbon_stock_inventory.get(method, {}).get(year, {}),
1175
+ cycle_inventory.get(year, {})
1176
+ ], dict())
1179
1177
  }
1180
1178
  } for method in measurement_method_ranking if should_run_group(method, year)
1181
1179
  ),
@@ -1205,15 +1203,22 @@ def _get_land_use_change_data(
1205
1203
  )
1206
1204
  )
1207
1205
 
1208
- delta_time = closest_inventory_year - year if closest_inventory_year else 0
1209
- inventory_data = land_use_inventory.get(closest_inventory_year, {})
1206
+ time_delta = closest_inventory_year - year if closest_inventory_year else 0
1207
+ prev_years_since_luc_event = (
1208
+ land_use_inventory.get(closest_inventory_year, {}).get(_InventoryKey.YEARS_SINCE_LUC_EVENT)
1209
+ )
1210
+ prev_years_since_inventory_start = (
1211
+ land_use_inventory.get(closest_inventory_year, {}).get(_InventoryKey.YEARS_SINCE_INVENTORY_START)
1212
+ )
1210
1213
 
1211
- years_since_luc_event = (
1212
- inventory_data.get(_InventoryKey.YEARS_SINCE_LUC_EVENT, _DEFAULT_YEARS_SINCE_LUC_EVENT) - delta_time
1214
+ years_since_luc_event = prev_years_since_luc_event - time_delta if prev_years_since_luc_event else None
1215
+ years_since_inventory_start = (
1216
+ prev_years_since_inventory_start - time_delta if prev_years_since_inventory_start else None
1213
1217
  )
1214
1218
 
1215
1219
  return {
1216
- _InventoryKey.YEARS_SINCE_LUC_EVENT: years_since_luc_event
1220
+ _InventoryKey.YEARS_SINCE_LUC_EVENT: years_since_luc_event,
1221
+ _InventoryKey.YEARS_SINCE_INVENTORY_START: years_since_inventory_start
1217
1222
  }
1218
1223
 
1219
1224
 
@@ -1408,25 +1413,54 @@ def create_run_function(
1408
1413
  """
1409
1414
  data = inventory[year]
1410
1415
  years_since_luc_event = data[_InventoryKey.YEARS_SINCE_LUC_EVENT]
1411
- emission_term_id = (
1412
- land_use_change_emission_term_id if years_since_luc_event <= _TRANSITION_PERIOD_YEARS
1413
- else management_change_emission_term_id
1414
- )
1416
+ years_since_inventory_start = data[_InventoryKey.YEARS_SINCE_INVENTORY_START]
1417
+
1418
+ is_luc_emission = bool(years_since_luc_event) and years_since_luc_event <= _TRANSITION_PERIOD_YEARS
1419
+ is_data_complete = bool(years_since_inventory_start) and years_since_inventory_start > _TRANSITION_PERIOD_YEARS
1420
+
1421
+ if is_luc_emission:
1422
+ # If LUC emission allocate emissions to land use change AND add corresponding zero emission to management
1423
+ emission_term_id = land_use_change_emission_term_id
1424
+ zero_emission_term_id = management_change_emission_term_id
1425
+ elif is_data_complete:
1426
+ # If management emission && data complete allocate emissions to management change AND add corresponding
1427
+ # zero emission to management
1428
+ emission_term_id = management_change_emission_term_id
1429
+ zero_emission_term_id = land_use_change_emission_term_id
1430
+ else:
1431
+ # If management emission, but not data complete allocate emissions to management change only
1432
+ emission_term_id = management_change_emission_term_id
1433
+ zero_emission_term_id = None
1415
1434
 
1416
1435
  rescaled_emission = _rescale_carbon_stock_change_emission(
1417
1436
  data[_InventoryKey.CO2_EMISSION], data[_InventoryKey.SHARE_OF_EMISSION][cycle_id]
1418
1437
  )
1419
1438
 
1439
+ zero_emission = CarbonStockChangeEmission(
1440
+ value=array(0),
1441
+ start_date=rescaled_emission.start_date,
1442
+ end_date=rescaled_emission.end_date,
1443
+ method=rescaled_emission.method
1444
+ ) if zero_emission_term_id else None
1445
+
1420
1446
  previous_emission = result.get(emission_term_id)
1447
+ previous_zero_emission = result.get(zero_emission_term_id)
1421
1448
 
1422
- update_dict = {
1449
+ emission_dict = {
1423
1450
  emission_term_id: (
1424
1451
  _add_carbon_stock_change_emissions(previous_emission, rescaled_emission) if previous_emission
1425
1452
  else rescaled_emission
1426
1453
  )
1427
1454
  }
1428
1455
 
1429
- return result | update_dict
1456
+ zero_emission_dict = {
1457
+ zero_emission_term_id: (
1458
+ _add_carbon_stock_change_emissions(previous_zero_emission, zero_emission) if previous_zero_emission
1459
+ else zero_emission
1460
+ )
1461
+ } if zero_emission_term_id else {}
1462
+
1463
+ return result | emission_dict | zero_emission_dict
1430
1464
 
1431
1465
  def run(cycle_id: str, cycle_start_date: str, cycle_end_date: str, inventory: dict) -> list[dict]:
1432
1466
  """
@@ -1447,9 +1481,13 @@ def create_run_function(
1447
1481
  list[dict]
1448
1482
  A list of [Emission](https://www.hestia.earth/schema/Emission) nodes containing model results.
1449
1483
  """
1484
+
1485
+ def should_run_year(year: int) -> bool:
1486
+ return cycle_id in inventory.get(year, {}).get(_InventoryKey.SHARE_OF_EMISSION, {}).keys()
1487
+
1450
1488
  assigned_emissions = reduce(
1451
1489
  lambda result, year: reduce_emissions(result, year, cycle_id, inventory),
1452
- inventory.keys(),
1490
+ (year for year in inventory.keys() if should_run_year(year)),
1453
1491
  {}
1454
1492
  )
1455
1493
 
@@ -1,3 +1,8 @@
1
+ """
2
+ `croppingDuration` can be added by the uploader for all crops, however the model `IPCC (2019)` will only run for
3
+ `riceGrainInHusk` or `ricePlantFlooded`.
4
+ The model will only run for rice crops as this is the only crop which requires the value for emission recalculations.
5
+ """
1
6
  from hestia_earth.schema import PracticeStatsDefinition
2
7
  from hestia_earth.utils.lookup import download_lookup, get_table_value, column_name
3
8
  from hestia_earth.utils.tools import safe_parse_float
@@ -219,18 +219,6 @@ _SOC_REFS = {
219
219
  }
220
220
 
221
221
  _LAND_USE_FACTORS = {
222
- IpccLandUseCategory.GRASSLAND: {
223
- EcoClimateZone.WARM_TEMPERATE_MOIST: {"value": 1},
224
- EcoClimateZone.WARM_TEMPERATE_DRY: {"value": 1},
225
- EcoClimateZone.COOL_TEMPERATE_MOIST: {"value": 1},
226
- EcoClimateZone.COOL_TEMPERATE_DRY: {"value": 1},
227
- EcoClimateZone.BOREAL_MOIST: {"value": 1},
228
- EcoClimateZone.BOREAL_DRY: {"value": 1},
229
- EcoClimateZone.TROPICAL_MONTANE: {"value": 1},
230
- EcoClimateZone.TROPICAL_WET: {"value": 1},
231
- EcoClimateZone.TROPICAL_MOIST: {"value": 1},
232
- EcoClimateZone.TROPICAL_DRY: {"value": 1}
233
- },
234
222
  IpccLandUseCategory.PERENNIAL_CROPS: {
235
223
  EcoClimateZone.WARM_TEMPERATE_MOIST: {"value": 0.72, "error": 22},
236
224
  EcoClimateZone.WARM_TEMPERATE_DRY: {"value": 0.72, "error": 22},
@@ -290,42 +278,6 @@ _LAND_USE_FACTORS = {
290
278
  EcoClimateZone.TROPICAL_WET: {"value": 0.82, "error": 17},
291
279
  EcoClimateZone.TROPICAL_MOIST: {"value": 0.82, "error": 17},
292
280
  EcoClimateZone.TROPICAL_DRY: {"value": 0.93, "error": 11}
293
- },
294
- IpccLandUseCategory.FOREST: {
295
- EcoClimateZone.WARM_TEMPERATE_MOIST: {"value": 1},
296
- EcoClimateZone.WARM_TEMPERATE_DRY: {"value": 1},
297
- EcoClimateZone.COOL_TEMPERATE_MOIST: {"value": 1},
298
- EcoClimateZone.COOL_TEMPERATE_DRY: {"value": 1},
299
- EcoClimateZone.BOREAL_MOIST: {"value": 1},
300
- EcoClimateZone.BOREAL_DRY: {"value": 1},
301
- EcoClimateZone.TROPICAL_MONTANE: {"value": 1},
302
- EcoClimateZone.TROPICAL_WET: {"value": 1},
303
- EcoClimateZone.TROPICAL_MOIST: {"value": 1},
304
- EcoClimateZone.TROPICAL_DRY: {"value": 1}
305
- },
306
- IpccLandUseCategory.NATIVE: {
307
- EcoClimateZone.WARM_TEMPERATE_MOIST: {"value": 1},
308
- EcoClimateZone.WARM_TEMPERATE_DRY: {"value": 1},
309
- EcoClimateZone.COOL_TEMPERATE_MOIST: {"value": 1},
310
- EcoClimateZone.COOL_TEMPERATE_DRY: {"value": 1},
311
- EcoClimateZone.BOREAL_MOIST: {"value": 1},
312
- EcoClimateZone.BOREAL_DRY: {"value": 1},
313
- EcoClimateZone.TROPICAL_MONTANE: {"value": 1},
314
- EcoClimateZone.TROPICAL_WET: {"value": 1},
315
- EcoClimateZone.TROPICAL_MOIST: {"value": 1},
316
- EcoClimateZone.TROPICAL_DRY: {"value": 1}
317
- },
318
- IpccLandUseCategory.OTHER: {
319
- EcoClimateZone.WARM_TEMPERATE_MOIST: {"value": 1},
320
- EcoClimateZone.WARM_TEMPERATE_DRY: {"value": 1},
321
- EcoClimateZone.COOL_TEMPERATE_MOIST: {"value": 1},
322
- EcoClimateZone.COOL_TEMPERATE_DRY: {"value": 1},
323
- EcoClimateZone.BOREAL_MOIST: {"value": 1},
324
- EcoClimateZone.BOREAL_DRY: {"value": 1},
325
- EcoClimateZone.TROPICAL_MONTANE: {"value": 1},
326
- EcoClimateZone.TROPICAL_WET: {"value": 1},
327
- EcoClimateZone.TROPICAL_MOIST: {"value": 1},
328
- EcoClimateZone.TROPICAL_DRY: {"value": 1}
329
281
  }
330
282
  }
331
283
 
@@ -366,30 +318,6 @@ _MANAGEMENT_FACTORS = {
366
318
  EcoClimateZone.TROPICAL_MOIST: {"value": 0.9, "error": 8},
367
319
  EcoClimateZone.TROPICAL_DRY: {"value": 0.9, "error": 8}
368
320
  },
369
- IpccManagementCategory.NOMINALLY_MANAGED: {
370
- EcoClimateZone.WARM_TEMPERATE_MOIST: {"value": 1},
371
- EcoClimateZone.WARM_TEMPERATE_DRY: {"value": 1},
372
- EcoClimateZone.COOL_TEMPERATE_MOIST: {"value": 1},
373
- EcoClimateZone.COOL_TEMPERATE_DRY: {"value": 1},
374
- EcoClimateZone.BOREAL_MOIST: {"value": 1},
375
- EcoClimateZone.BOREAL_DRY: {"value": 1},
376
- EcoClimateZone.TROPICAL_MONTANE: {"value": 1},
377
- EcoClimateZone.TROPICAL_WET: {"value": 1},
378
- EcoClimateZone.TROPICAL_MOIST: {"value": 1},
379
- EcoClimateZone.TROPICAL_DRY: {"value": 1}
380
- },
381
- IpccManagementCategory.FULL_TILLAGE: {
382
- EcoClimateZone.WARM_TEMPERATE_MOIST: {"value": 1},
383
- EcoClimateZone.WARM_TEMPERATE_DRY: {"value": 1},
384
- EcoClimateZone.COOL_TEMPERATE_MOIST: {"value": 1},
385
- EcoClimateZone.COOL_TEMPERATE_DRY: {"value": 1},
386
- EcoClimateZone.BOREAL_MOIST: {"value": 1},
387
- EcoClimateZone.BOREAL_DRY: {"value": 1},
388
- EcoClimateZone.TROPICAL_MONTANE: {"value": 1},
389
- EcoClimateZone.TROPICAL_WET: {"value": 1},
390
- EcoClimateZone.TROPICAL_MOIST: {"value": 1},
391
- EcoClimateZone.TROPICAL_DRY: {"value": 1}
392
- },
393
321
  IpccManagementCategory.REDUCED_TILLAGE: {
394
322
  EcoClimateZone.WARM_TEMPERATE_MOIST: {"value": 1.05, "error": 4},
395
323
  EcoClimateZone.WARM_TEMPERATE_DRY: {"value": 0.99, "error": 3},
@@ -413,18 +341,6 @@ _MANAGEMENT_FACTORS = {
413
341
  EcoClimateZone.TROPICAL_WET: {"value": 1.1, "error": 5},
414
342
  EcoClimateZone.TROPICAL_MOIST: {"value": 1.1, "error": 5},
415
343
  EcoClimateZone.TROPICAL_DRY: {"value": 1.04, "error": 7}
416
- },
417
- IpccManagementCategory.OTHER: {
418
- EcoClimateZone.WARM_TEMPERATE_MOIST: {"value": 1},
419
- EcoClimateZone.WARM_TEMPERATE_DRY: {"value": 1},
420
- EcoClimateZone.COOL_TEMPERATE_MOIST: {"value": 1},
421
- EcoClimateZone.COOL_TEMPERATE_DRY: {"value": 1},
422
- EcoClimateZone.BOREAL_MOIST: {"value": 1},
423
- EcoClimateZone.BOREAL_DRY: {"value": 1},
424
- EcoClimateZone.TROPICAL_MONTANE: {"value": 1},
425
- EcoClimateZone.TROPICAL_WET: {"value": 1},
426
- EcoClimateZone.TROPICAL_MOIST: {"value": 1},
427
- EcoClimateZone.TROPICAL_DRY: {"value": 1}
428
344
  }
429
345
  }
430
346
 
@@ -441,18 +357,6 @@ _CARBON_INPUT_FACTORS = {
441
357
  EcoClimateZone.TROPICAL_MOIST: {"value": 1.11, "error": 7},
442
358
  EcoClimateZone.TROPICAL_DRY: {"value": 1.11, "error": 7}
443
359
  },
444
- IpccCarbonInputCategory.GRASSLAND_MEDIUM: {
445
- EcoClimateZone.WARM_TEMPERATE_MOIST: {"value": 1},
446
- EcoClimateZone.WARM_TEMPERATE_DRY: {"value": 1},
447
- EcoClimateZone.COOL_TEMPERATE_MOIST: {"value": 1},
448
- EcoClimateZone.COOL_TEMPERATE_DRY: {"value": 1},
449
- EcoClimateZone.BOREAL_MOIST: {"value": 1},
450
- EcoClimateZone.BOREAL_DRY: {"value": 1},
451
- EcoClimateZone.TROPICAL_MONTANE: {"value": 1},
452
- EcoClimateZone.TROPICAL_WET: {"value": 1},
453
- EcoClimateZone.TROPICAL_MOIST: {"value": 1},
454
- EcoClimateZone.TROPICAL_DRY: {"value": 1}
455
- },
456
360
  IpccCarbonInputCategory.CROPLAND_HIGH_WITH_MANURE: {
457
361
  EcoClimateZone.WARM_TEMPERATE_MOIST: {"value": 1.44, "error": 13},
458
362
  EcoClimateZone.WARM_TEMPERATE_DRY: {"value": 1.37, "error": 12},
@@ -477,18 +381,6 @@ _CARBON_INPUT_FACTORS = {
477
381
  EcoClimateZone.TROPICAL_MOIST: {"value": 1.11, "error": 10},
478
382
  EcoClimateZone.TROPICAL_DRY: {"value": 1.04, "error": 13}
479
383
  },
480
- IpccCarbonInputCategory.CROPLAND_MEDIUM: {
481
- EcoClimateZone.WARM_TEMPERATE_MOIST: {"value": 1},
482
- EcoClimateZone.WARM_TEMPERATE_DRY: {"value": 1},
483
- EcoClimateZone.COOL_TEMPERATE_MOIST: {"value": 1},
484
- EcoClimateZone.COOL_TEMPERATE_DRY: {"value": 1},
485
- EcoClimateZone.BOREAL_MOIST: {"value": 1},
486
- EcoClimateZone.BOREAL_DRY: {"value": 1},
487
- EcoClimateZone.TROPICAL_MONTANE: {"value": 1},
488
- EcoClimateZone.TROPICAL_WET: {"value": 1},
489
- EcoClimateZone.TROPICAL_MOIST: {"value": 1},
490
- EcoClimateZone.TROPICAL_DRY: {"value": 1}
491
- },
492
384
  IpccCarbonInputCategory.CROPLAND_LOW: {
493
385
  EcoClimateZone.WARM_TEMPERATE_MOIST: {"value": 0.92, "error": 14},
494
386
  EcoClimateZone.WARM_TEMPERATE_DRY: {"value": 0.95, "error": 13},
@@ -500,18 +392,6 @@ _CARBON_INPUT_FACTORS = {
500
392
  EcoClimateZone.TROPICAL_WET: {"value": 0.92, "error": 14},
501
393
  EcoClimateZone.TROPICAL_MOIST: {"value": 0.92, "error": 14},
502
394
  EcoClimateZone.TROPICAL_DRY: {"value": 0.95, "error": 13}
503
- },
504
- IpccCarbonInputCategory.OTHER: {
505
- EcoClimateZone.WARM_TEMPERATE_MOIST: {"value": 1},
506
- EcoClimateZone.WARM_TEMPERATE_DRY: {"value": 1},
507
- EcoClimateZone.COOL_TEMPERATE_MOIST: {"value": 1},
508
- EcoClimateZone.COOL_TEMPERATE_DRY: {"value": 1},
509
- EcoClimateZone.BOREAL_MOIST: {"value": 1},
510
- EcoClimateZone.BOREAL_DRY: {"value": 1},
511
- EcoClimateZone.TROPICAL_MONTANE: {"value": 1},
512
- EcoClimateZone.TROPICAL_WET: {"value": 1},
513
- EcoClimateZone.TROPICAL_MOIST: {"value": 1},
514
- EcoClimateZone.TROPICAL_DRY: {"value": 1}
515
395
  }
516
396
  }
517
397
 
@@ -556,7 +436,7 @@ def _sample_parameter(
556
436
  The sampled parameter as a numpy array with shape `(1, iterations)`.
557
437
  """
558
438
  parameter_dict = _IPCC_CATEGORY_TO_FACTOR_DICT.get(type(parameter))
559
- kwargs = parameter_dict.get(parameter, {}).get(eco_climate_zone, {})
439
+ kwargs = parameter_dict.get(parameter, {}).get(eco_climate_zone, {"value": 1})
560
440
  func = _get_sample_func(kwargs)
561
441
  return func(iterations=iterations, seed=seed, **kwargs)
562
442
 
@@ -1008,7 +888,7 @@ def _compile_inventory(
1008
888
 
1009
889
  # If no `landCover` nodes in `site.management` use `site.siteType` to assign static `IpccLandUseCategory`.
1010
890
  run_with_site_type = len(filter_list_term_type(management_nodes, [TermTermType.LANDCOVER])) == 0
1011
- site_type_ipcc_land_use_category = SITE_TYPE_TO_IPCC_LAND_USE_CATEGORY.get(site_type, IpccLandUseCategory.OTHER)
891
+ site_type_ipcc_land_use_category = SITE_TYPE_TO_IPCC_LAND_USE_CATEGORY.get(site_type, IpccLandUseCategory.UNKNOWN)
1012
892
 
1013
893
  grouped_management = group_nodes_by_year(management_nodes)
1014
894
 
@@ -1213,7 +1093,7 @@ def _assign_ipcc_land_use_category(
1213
1093
  Assigned IPCC land use category.
1214
1094
  """
1215
1095
  DECISION_TREE = _LAND_USE_CATEGORY_DECISION_TREE
1216
- DEFAULT = IpccLandUseCategory.OTHER
1096
+ DEFAULT = IpccLandUseCategory.UNKNOWN
1217
1097
 
1218
1098
  cover_crop_nodes, land_cover_nodes = split_on_condition(
1219
1099
  filter_list_term_type(management_nodes, [TermTermType.LANDCOVER]),
@@ -1389,7 +1269,7 @@ def _assign_ipcc_management_category(
1389
1269
  """
1390
1270
  decision_tree = _IPCC_LAND_USE_CATEGORY_TO_DECISION_TREE.get(ipcc_land_use_category, {})
1391
1271
  default = _IPCC_LAND_USE_CATEGORY_TO_DEFAULT_IPCC_MANAGEMENT_CATEGORY.get(
1392
- ipcc_land_use_category, IpccManagementCategory.OTHER
1272
+ ipcc_land_use_category, IpccManagementCategory.NOT_RELEVANT
1393
1273
  )
1394
1274
 
1395
1275
  land_cover_nodes = filter_list_term_type(management_nodes, [TermTermType.LANDCOVER])
@@ -1431,10 +1311,10 @@ def _check_grassland_ipcc_management_category(
1431
1311
  bool
1432
1312
  `True` if the conditions match the specified management category, `False` otherwise.
1433
1313
  """
1434
- target_term_id = IPCC_MANAGEMENT_CATEGORY_TO_GRASSLAND_MANAGEMENT_TERM_ID.get(key, None)
1314
+ target_term_ids = IPCC_MANAGEMENT_CATEGORY_TO_GRASSLAND_MANAGEMENT_TERM_ID.get(key, None)
1435
1315
  return cumulative_nodes_term_match(
1436
1316
  land_cover_nodes,
1437
- target_term_ids=target_term_id,
1317
+ target_term_ids=target_term_ids,
1438
1318
  cumulative_threshold=MIN_AREA_THRESHOLD
1439
1319
  )
1440
1320
 
@@ -1443,8 +1323,7 @@ _GRASSLAND_IPCC_MANAGEMENT_CATEGORY_DECISION_TREE = {
1443
1323
  IpccManagementCategory.SEVERELY_DEGRADED: _check_grassland_ipcc_management_category,
1444
1324
  IpccManagementCategory.IMPROVED_GRASSLAND: _check_grassland_ipcc_management_category,
1445
1325
  IpccManagementCategory.HIGH_INTENSITY_GRAZING: _check_grassland_ipcc_management_category,
1446
- IpccManagementCategory.NOMINALLY_MANAGED: _check_grassland_ipcc_management_category,
1447
- IpccManagementCategory.OTHER: _check_grassland_ipcc_management_category
1326
+ IpccManagementCategory.NOMINALLY_MANAGED: _check_grassland_ipcc_management_category
1448
1327
  }
1449
1328
  """
1450
1329
  Decision tree mapping IPCC management categories to corresponding check functions for grassland.
@@ -1508,9 +1387,9 @@ Value: Corresponding decision tree for IPCC management categories based on land
1508
1387
  """
1509
1388
 
1510
1389
  _IPCC_LAND_USE_CATEGORY_TO_DEFAULT_IPCC_MANAGEMENT_CATEGORY = {
1511
- IpccLandUseCategory.GRASSLAND: IpccManagementCategory.NOMINALLY_MANAGED,
1512
- IpccLandUseCategory.ANNUAL_CROPS_WET: IpccManagementCategory.FULL_TILLAGE,
1513
- IpccLandUseCategory.ANNUAL_CROPS: IpccManagementCategory.FULL_TILLAGE
1390
+ IpccLandUseCategory.GRASSLAND: IpccManagementCategory.UNKNOWN,
1391
+ IpccLandUseCategory.ANNUAL_CROPS_WET: IpccManagementCategory.UNKNOWN,
1392
+ IpccLandUseCategory.ANNUAL_CROPS: IpccManagementCategory.UNKNOWN
1514
1393
  }
1515
1394
  """
1516
1395
  Mapping of default IPCC management categories for each IPCC land use category.
@@ -1540,7 +1419,9 @@ def _assign_ipcc_carbon_input_category(
1540
1419
  Assigned IPCC Carbon Input Category.
1541
1420
  """
1542
1421
  decision_tree = _DECISION_TREE_FROM_IPCC_MANAGEMENT_CATEGORY.get(ipcc_management_category, {})
1543
- default = _DEFAULT_CARBON_INPUT_CATEGORY.get(ipcc_management_category, IpccCarbonInputCategory.OTHER)
1422
+ default = _DEFAULT_CARBON_INPUT_CATEGORY.get(
1423
+ ipcc_management_category, IpccCarbonInputCategory.NOT_RELEVANT
1424
+ )
1544
1425
 
1545
1426
  should_run_ = len(management_nodes) > 0
1546
1427
 
@@ -1577,7 +1458,7 @@ def _check_grassland_ipcc_carbon_input_category(
1577
1458
 
1578
1459
  _GRASSLAND_IPCC_CARBON_INPUT_CATEGORY_TO_MIN_NUM_IMPROVEMENTS = {
1579
1460
  IpccCarbonInputCategory.GRASSLAND_HIGH: 2,
1580
- IpccCarbonInputCategory.GRASSLAND_MEDIUM: 1
1461
+ IpccCarbonInputCategory.GRASSLAND_MEDIUM: 0
1581
1462
  }
1582
1463
  """
1583
1464
  A mapping from IPCC Grassland Carbon Input Categories to the minimum number of improvements required.
@@ -1898,10 +1779,10 @@ Value: Decision tree for Carbon Input Categories corresponding to the management
1898
1779
  """
1899
1780
 
1900
1781
  _DEFAULT_CARBON_INPUT_CATEGORY = {
1901
- IpccManagementCategory.IMPROVED_GRASSLAND: IpccCarbonInputCategory.GRASSLAND_MEDIUM,
1902
- IpccManagementCategory.FULL_TILLAGE: IpccCarbonInputCategory.CROPLAND_LOW,
1903
- IpccManagementCategory.REDUCED_TILLAGE: IpccCarbonInputCategory.CROPLAND_LOW,
1904
- IpccManagementCategory.NO_TILLAGE: IpccCarbonInputCategory.CROPLAND_LOW
1782
+ IpccManagementCategory.IMPROVED_GRASSLAND: IpccCarbonInputCategory.UNKNOWN,
1783
+ IpccManagementCategory.FULL_TILLAGE: IpccCarbonInputCategory.UNKNOWN,
1784
+ IpccManagementCategory.REDUCED_TILLAGE: IpccCarbonInputCategory.UNKNOWN,
1785
+ IpccManagementCategory.NO_TILLAGE: IpccCarbonInputCategory.UNKNOWN
1905
1786
  }
1906
1787
  """
1907
1788
  A mapping from IPCC Management Categories to default Carbon Input Categories.
@@ -2030,8 +1911,10 @@ def _should_run_inventory_year(group: dict) -> bool:
2030
1911
  """
2031
1912
  Determines whether there is sufficient data in an inventory year to run the tier 1 model.
2032
1913
 
2033
- 1. Check if the land use category is not "OTHER"
2034
- 2. Check if all required keys are present.
1914
+ 1. Check if all required keys are present.
1915
+ 2. Check if the land use category is not "OTHER" or "UNKNOWN"
1916
+ 3. Check if the management category is not "UNKNOWN"
1917
+ 4. Check if the carbon input category is not "UNKNOWN"
2035
1918
 
2036
1919
  Parameters
2037
1920
  ----------
@@ -2043,7 +1926,8 @@ def _should_run_inventory_year(group: dict) -> bool:
2043
1926
  bool
2044
1927
  True if the inventory year is valid, False otherwise.
2045
1928
  """
2046
- return all([
2047
- group.get(_InventoryKey.LU_CATEGORY) != IpccLandUseCategory.OTHER,
2048
- all(key in group.keys() for key in _REQUIRED_KEYS),
1929
+ return all(key in group.keys() for key in _REQUIRED_KEYS) and all([
1930
+ group.get(_InventoryKey.LU_CATEGORY) not in [IpccLandUseCategory.OTHER, IpccLandUseCategory.UNKNOWN],
1931
+ group.get(_InventoryKey.MG_CATEGORY) not in [IpccManagementCategory.UNKNOWN],
1932
+ group.get(_InventoryKey.CI_CATEGORY) not in [IpccCarbonInputCategory.UNKNOWN]
2049
1933
  ])
@@ -765,7 +765,7 @@ def _get_f_2_annual(
765
765
  Get the value of `f_2` (the stabilisation efficiencies for structural decay products entering the active pool)
766
766
  based on the tillage `IpccManagementCategory`.
767
767
 
768
- If tillage regime is unknown, `IpccManagementCategory.OTHER` should be assumed.
768
+ If tillage regime is unknown, `IpccManagementCategory.UNKNOWN` should be assumed.
769
769
 
770
770
  Parameters
771
771
  ----------
@@ -793,7 +793,7 @@ def _get_f_2_annual(
793
793
  IpccManagementCategory.FULL_TILLAGE: f_2_full_tillage,
794
794
  IpccManagementCategory.REDUCED_TILLAGE: f_2_reduced_tillage,
795
795
  IpccManagementCategory.NO_TILLAGE: f_2_no_tillage,
796
- IpccManagementCategory.OTHER: f_2_unknown_tillage
796
+ IpccManagementCategory.UNKNOWN: f_2_unknown_tillage
797
797
  }
798
798
  default = f_2_unknown_tillage
799
799
  return vstack([ipcc_tillage_management_category_to_f_2s.get(till, default) for till in tillage_category_annual])
@@ -1611,7 +1611,7 @@ def _get_grouped_tillage_categories(grouped_cycles):
1611
1611
 
1612
1612
  def _assign_tier_2_ipcc_tillage_management_category(
1613
1613
  cycles: list[dict],
1614
- default: IpccManagementCategory = IpccManagementCategory.OTHER
1614
+ default: IpccManagementCategory = IpccManagementCategory.UNKNOWN
1615
1615
  ) -> IpccManagementCategory:
1616
1616
  """
1617
1617
  Assigns a tillage `IpccManagementCategory` to a list of HESTIA `Cycle`s.
@@ -65,6 +65,7 @@ class IpccLandUseCategory(Enum):
65
65
  FOREST = "forest"
66
66
  NATIVE = "native"
67
67
  OTHER = "other"
68
+ UNKNOWN = "unknown"
68
69
 
69
70
 
70
71
  SITE_TYPE_TO_IPCC_LAND_USE_CATEGORY = {
@@ -84,7 +85,8 @@ IPCC_LAND_USE_CATEGORY_TO_LAND_COVER_LOOKUP_VALUE = {
84
85
  IpccLandUseCategory.ANNUAL_CROPS: "Annual crops",
85
86
  IpccLandUseCategory.SET_ASIDE: "Set aside",
86
87
  IpccLandUseCategory.FOREST: "Forest",
87
- IpccLandUseCategory.NATIVE: "Native"
88
+ IpccLandUseCategory.NATIVE: "Native",
89
+ IpccLandUseCategory.OTHER: "Other"
88
90
  }
89
91
  """
90
92
  A dictionary mapping IPCC land use categories to corresponding land cover lookup values in the
@@ -106,15 +108,15 @@ class IpccManagementCategory(Enum):
106
108
  FULL_TILLAGE = "full tillage"
107
109
  REDUCED_TILLAGE = "reduced tillage"
108
110
  NO_TILLAGE = "no tillage"
109
- OTHER = "other"
111
+ UNKNOWN = "unknown"
112
+ NOT_RELEVANT = "not relevant"
110
113
 
111
114
 
112
115
  IPCC_MANAGEMENT_CATEGORY_TO_GRASSLAND_MANAGEMENT_TERM_ID = {
113
116
  IpccManagementCategory.SEVERELY_DEGRADED: "severelyDegradedPasture",
114
117
  IpccManagementCategory.IMPROVED_GRASSLAND: "improvedPasture",
115
118
  IpccManagementCategory.HIGH_INTENSITY_GRAZING: "highIntensityGrazingPasture",
116
- IpccManagementCategory.NOMINALLY_MANAGED: "nominallyManagedPasture",
117
- IpccManagementCategory.OTHER: "nativePasture"
119
+ IpccManagementCategory.NOMINALLY_MANAGED: ["nominallyManagedPasture", "nativePasture"]
118
120
  }
119
121
  """
120
122
  A dictionary mapping IPCC management categories to corresponding grassland management term IDs from the land cover
@@ -146,7 +148,8 @@ class IpccCarbonInputCategory(Enum):
146
148
  CROPLAND_HIGH_WITHOUT_MANURE = "cropland high (without manure)"
147
149
  CROPLAND_MEDIUM = "cropland medium"
148
150
  CROPLAND_LOW = "cropland low"
149
- OTHER = "other"
151
+ UNKNOWN = "unknown"
152
+ NOT_RELEVANT = "not relevant"
150
153
 
151
154
 
152
155
  CarbonSource = NamedTuple(
@@ -30,7 +30,8 @@ REQUIREMENTS = {
30
30
  }
31
31
  RETURNS = {
32
32
  "Indicator": [{
33
- "value": ""
33
+ "value": "",
34
+ "inputs": ""
34
35
  }]
35
36
  }
36
37
  TERM_ID = 'freshwaterWithdrawalsInputsProduction'
@@ -31,6 +31,7 @@ REQUIREMENTS = {
31
31
  RETURNS = {
32
32
  "Indicator": [{
33
33
  "value": "",
34
+ "inputs": "",
34
35
  "landCover": ""
35
36
  }]
36
37
  }
@@ -31,6 +31,7 @@ REQUIREMENTS = {
31
31
  RETURNS = {
32
32
  "Indicator": [{
33
33
  "value": "",
34
+ "inputs": "",
34
35
  "landCover": "",
35
36
  "previousLandCover": ""
36
37
  }]
@@ -31,6 +31,7 @@ REQUIREMENTS = {
31
31
  RETURNS = {
32
32
  "Indicator": [{
33
33
  "value": "",
34
+ "inputs": "",
34
35
  "landCover": "",
35
36
  "previousLandCover": ""
36
37
  }]