hestia-earth-models 0.64.9__py3-none-any.whl → 0.64.11__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 (125) hide show
  1. hestia_earth/models/cml2001Baseline/abioticResourceDepletionFossilFuels.py +175 -0
  2. hestia_earth/models/cml2001Baseline/abioticResourceDepletionMineralsAndMetals.py +136 -0
  3. hestia_earth/models/cml2001Baseline/eutrophicationPotentialExcludingFate.py +2 -2
  4. hestia_earth/models/cml2001Baseline/terrestrialAcidificationPotentialIncludingFateAverageEurope.py +2 -2
  5. hestia_earth/models/cml2001NonBaseline/eutrophicationPotentialIncludingFateAverageEurope.py +2 -2
  6. hestia_earth/models/cml2001NonBaseline/terrestrialAcidificationPotentialExcludingFate.py +2 -2
  7. hestia_earth/models/cycle/completeness/cropResidue.py +15 -10
  8. hestia_earth/models/cycle/completeness/freshForage.py +60 -0
  9. hestia_earth/models/edip2003/ozoneDepletionPotential.py +2 -2
  10. hestia_earth/models/environmentalFootprintV3/soilQualityIndexLandTransformation.py +2 -2
  11. hestia_earth/models/fantkeEtAl2016/damageToHumanHealthParticulateMatterFormation.py +7 -17
  12. hestia_earth/models/ipcc2013ExcludingFeedbacks/gwp100.py +2 -2
  13. hestia_earth/models/ipcc2013IncludingFeedbacks/gwp100.py +2 -2
  14. hestia_earth/models/ipcc2019/aboveGroundBiomass.py +31 -243
  15. hestia_earth/models/ipcc2019/belowGroundBiomass.py +529 -0
  16. hestia_earth/models/ipcc2019/biomass_utils.py +406 -0
  17. hestia_earth/models/ipcc2019/{co2ToAirAboveGroundBiomassStockChangeLandUseChange.py → co2ToAirAboveGroundBiomassStockChange.py} +19 -7
  18. hestia_earth/models/ipcc2019/{co2ToAirBelowGroundBiomassStockChangeLandUseChange.py → co2ToAirBelowGroundBiomassStockChange.py} +19 -7
  19. hestia_earth/models/ipcc2019/co2ToAirCarbonStockChange_utils.py +402 -73
  20. hestia_earth/models/ipcc2019/{co2ToAirSoilOrganicCarbonStockChangeManagementChange.py → co2ToAirSoilOrganicCarbonStockChange.py} +20 -8
  21. hestia_earth/models/ipcc2019/organicCarbonPerHa.py +3 -1
  22. hestia_earth/models/ipcc2019/pastureGrass_utils.py +6 -7
  23. hestia_earth/models/ipcc2021/gwp100.py +2 -2
  24. hestia_earth/models/lcImpactAllEffects100Years/damageToFreshwaterEcosystemsClimateChange.py +2 -2
  25. hestia_earth/models/lcImpactAllEffects100Years/damageToFreshwaterEcosystemsFreshwaterEutrophication.py +2 -2
  26. hestia_earth/models/lcImpactAllEffects100Years/damageToFreshwaterEcosystemsWaterStress.py +2 -2
  27. hestia_earth/models/lcImpactAllEffects100Years/damageToHumanHealthClimateChange.py +2 -2
  28. hestia_earth/models/lcImpactAllEffects100Years/damageToHumanHealthParticulateMatterFormation.py +2 -2
  29. hestia_earth/models/lcImpactAllEffects100Years/damageToHumanHealthPhotochemicalOzoneFormation.py +2 -2
  30. hestia_earth/models/lcImpactAllEffects100Years/damageToHumanHealthStratosphericOzoneDepletion.py +2 -2
  31. hestia_earth/models/lcImpactAllEffects100Years/damageToHumanHealthWaterStress.py +2 -2
  32. hestia_earth/models/lcImpactAllEffects100Years/damageToMarineEcosystemsMarineEutrophication.py +2 -2
  33. hestia_earth/models/lcImpactAllEffects100Years/damageToTerrestrialEcosystemsClimateChange.py +2 -2
  34. hestia_earth/models/lcImpactAllEffects100Years/damageToTerrestrialEcosystemsPhotochemicalOzoneFormation.py +2 -2
  35. hestia_earth/models/lcImpactAllEffects100Years/damageToTerrestrialEcosystemsTerrestrialAcidification.py +2 -2
  36. hestia_earth/models/lcImpactAllEffectsInfinite/damageToFreshwaterEcosystemsClimateChange.py +2 -2
  37. hestia_earth/models/lcImpactAllEffectsInfinite/damageToFreshwaterEcosystemsFreshwaterEutrophication.py +2 -2
  38. hestia_earth/models/lcImpactAllEffectsInfinite/damageToFreshwaterEcosystemsWaterStress.py +2 -2
  39. hestia_earth/models/lcImpactAllEffectsInfinite/damageToHumanHealthClimateChange.py +2 -2
  40. hestia_earth/models/lcImpactAllEffectsInfinite/damageToHumanHealthParticulateMatterFormation.py +2 -2
  41. hestia_earth/models/lcImpactAllEffectsInfinite/damageToHumanHealthPhotochemicalOzoneFormation.py +2 -2
  42. hestia_earth/models/lcImpactAllEffectsInfinite/damageToHumanHealthStratosphericOzoneDepletion.py +2 -2
  43. hestia_earth/models/lcImpactAllEffectsInfinite/damageToHumanHealthWaterStress.py +2 -2
  44. hestia_earth/models/lcImpactAllEffectsInfinite/damageToMarineEcosystemsMarineEutrophication.py +2 -2
  45. hestia_earth/models/lcImpactAllEffectsInfinite/damageToTerrestrialEcosystemsClimateChange.py +2 -2
  46. hestia_earth/models/lcImpactAllEffectsInfinite/damageToTerrestrialEcosystemsPhotochemicalOzoneFormation.py +2 -2
  47. hestia_earth/models/lcImpactAllEffectsInfinite/damageToTerrestrialEcosystemsTerrestrialAcidification.py +2 -2
  48. hestia_earth/models/lcImpactCertainEffects100Years/damageToFreshwaterEcosystemsFreshwaterEutrophication.py +2 -2
  49. hestia_earth/models/lcImpactCertainEffects100Years/damageToFreshwaterEcosystemsWaterStress.py +2 -2
  50. hestia_earth/models/lcImpactCertainEffects100Years/damageToHumanHealthClimateChange.py +2 -2
  51. hestia_earth/models/lcImpactCertainEffects100Years/damageToHumanHealthParticulateMatterFormation.py +2 -2
  52. hestia_earth/models/lcImpactCertainEffects100Years/damageToHumanHealthPhotochemicalOzoneFormation.py +2 -2
  53. hestia_earth/models/lcImpactCertainEffects100Years/damageToHumanHealthStratosphericOzoneDepletion.py +2 -2
  54. hestia_earth/models/lcImpactCertainEffects100Years/damageToHumanHealthWaterStress.py +2 -2
  55. hestia_earth/models/lcImpactCertainEffects100Years/damageToMarineEcosystemsMarineEutrophication.py +2 -2
  56. hestia_earth/models/lcImpactCertainEffects100Years/damageToTerrestrialEcosystemsClimateChange.py +2 -2
  57. hestia_earth/models/lcImpactCertainEffects100Years/damageToTerrestrialEcosystemsPhotochemicalOzoneFormation.py +2 -2
  58. hestia_earth/models/lcImpactCertainEffects100Years/damageToTerrestrialEcosystemsTerrestrialAcidification.py +2 -2
  59. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToFreshwaterEcosystemsFreshwaterEutrophication.py +2 -2
  60. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToFreshwaterEcosystemsWaterStress.py +2 -2
  61. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToHumanHealthClimateChange.py +2 -2
  62. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToHumanHealthParticulateMatterFormation.py +2 -2
  63. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToHumanHealthPhotochemicalOzoneFormation.py +2 -2
  64. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToHumanHealthStratosphericOzoneDepletion.py +2 -2
  65. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToHumanHealthWaterStress.py +2 -2
  66. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToMarineEcosystemsMarineEutrophication.py +2 -2
  67. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToTerrestrialEcosystemsClimateChange.py +2 -2
  68. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToTerrestrialEcosystemsPhotochemicalOzoneFormation.py +2 -2
  69. hestia_earth/models/lcImpactCertainEffectsInfinite/damageToTerrestrialEcosystemsTerrestrialAcidification.py +2 -2
  70. hestia_earth/models/mocking/build_mock_search.py +44 -0
  71. hestia_earth/models/mocking/mock_search.py +8 -49
  72. hestia_earth/models/mocking/search-results.json +3055 -558
  73. hestia_earth/models/poschEtAl2008/terrestrialAcidificationPotentialAccumulatedExceedance.py +3 -3
  74. hestia_earth/models/poschEtAl2008/terrestrialEutrophicationPotentialAccumulatedExceedance.py +3 -3
  75. hestia_earth/models/preload_requests.py +1 -1
  76. hestia_earth/models/recipe2016Egalitarian/ecosystemDamageOzoneFormation.py +2 -2
  77. hestia_earth/models/recipe2016Egalitarian/freshwaterEutrophicationPotential.py +2 -2
  78. hestia_earth/models/recipe2016Egalitarian/humanDamageOzoneFormation.py +2 -2
  79. hestia_earth/models/recipe2016Egalitarian/marineEutrophicationPotential.py +2 -2
  80. hestia_earth/models/recipe2016Egalitarian/ozoneDepletionPotential.py +2 -2
  81. hestia_earth/models/recipe2016Egalitarian/terrestrialAcidificationPotential.py +2 -2
  82. hestia_earth/models/recipe2016Hierarchist/ecosystemDamageOzoneFormation.py +2 -2
  83. hestia_earth/models/recipe2016Hierarchist/freshwaterEutrophicationPotential.py +2 -2
  84. hestia_earth/models/recipe2016Hierarchist/humanDamageOzoneFormation.py +2 -2
  85. hestia_earth/models/recipe2016Hierarchist/marineEutrophicationPotential.py +2 -2
  86. hestia_earth/models/recipe2016Hierarchist/ozoneDepletionPotential.py +2 -2
  87. hestia_earth/models/recipe2016Hierarchist/terrestrialAcidificationPotential.py +2 -2
  88. hestia_earth/models/recipe2016Individualist/ecosystemDamageOzoneFormation.py +2 -2
  89. hestia_earth/models/recipe2016Individualist/freshwaterEutrophicationPotential.py +2 -2
  90. hestia_earth/models/recipe2016Individualist/humanDamageOzoneFormation.py +2 -2
  91. hestia_earth/models/recipe2016Individualist/marineEutrophicationPotential.py +2 -2
  92. hestia_earth/models/recipe2016Individualist/ozoneDepletionPotential.py +2 -2
  93. hestia_earth/models/recipe2016Individualist/terrestrialAcidificationPotential.py +2 -2
  94. hestia_earth/models/schmidt2007/utils.py +13 -4
  95. hestia_earth/models/utils/blank_node.py +73 -3
  96. hestia_earth/models/utils/constant.py +8 -1
  97. hestia_earth/models/utils/cycle.py +10 -13
  98. hestia_earth/models/utils/fuel.py +1 -1
  99. hestia_earth/models/utils/impact_assessment.py +49 -24
  100. hestia_earth/models/utils/lookup.py +36 -7
  101. hestia_earth/models/utils/pesticideAI.py +1 -1
  102. hestia_earth/models/utils/property.py +11 -4
  103. hestia_earth/models/utils/term.py +15 -8
  104. hestia_earth/models/version.py +1 -1
  105. {hestia_earth_models-0.64.9.dist-info → hestia_earth_models-0.64.11.dist-info}/METADATA +2 -2
  106. {hestia_earth_models-0.64.9.dist-info → hestia_earth_models-0.64.11.dist-info}/RECORD +123 -114
  107. {hestia_earth_models-0.64.9.dist-info → hestia_earth_models-0.64.11.dist-info}/WHEEL +1 -1
  108. tests/models/cml2001Baseline/test_abioticResourceDepletionFossilFuels.py +196 -0
  109. tests/models/cml2001Baseline/test_abioticResourceDepletionMineralsAndMetals.py +124 -0
  110. tests/models/cycle/completeness/test_freshForage.py +21 -0
  111. tests/models/edip2003/test_ozoneDepletionPotential.py +1 -13
  112. tests/models/environmentalFootprintV3/test_soilQualityIndexLandTransformation.py +1 -2
  113. tests/models/impact_assessment/test_emissions.py +1 -0
  114. tests/models/ipcc2019/test_aboveGroundBiomass.py +27 -63
  115. tests/models/ipcc2019/test_belowGroundBiomass.py +146 -0
  116. tests/models/ipcc2019/test_biomass_utils.py +115 -0
  117. tests/models/ipcc2019/{test_co2ToAirAboveGroundBiomassStockChangeLandUseChange.py → test_co2ToAirAboveGroundBiomassStockChange.py} +5 -5
  118. tests/models/ipcc2019/{test_co2ToAirBelowGroundBiomassStockChangeLandUseChange.py → test_co2ToAirBelowGroundBiomassStockChange.py} +5 -5
  119. tests/models/ipcc2019/{test_co2ToAirSoilOrganicCarbonStockChangeManagementChange.py → test_co2ToAirSoilOrganicCarbonStockChange.py} +5 -5
  120. tests/models/ipcc2021/test_gwp100.py +2 -2
  121. tests/models/utils/test_impact_assessment.py +3 -3
  122. hestia_earth/models/ipcc2019/aboveGroundBiomass_utils.py +0 -180
  123. tests/models/ipcc2019/test_aboveGroundBiomass_utils.py +0 -92
  124. {hestia_earth_models-0.64.9.dist-info → hestia_earth_models-0.64.11.dist-info}/LICENSE +0 -0
  125. {hestia_earth_models-0.64.9.dist-info → hestia_earth_models-0.64.11.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,115 @@
1
+ from pytest import mark
2
+
3
+ from hestia_earth.models.ipcc2019.biomass_utils import (
4
+ _assign_biomass_category, _get_sample_func, _rescale_category_cover, BiomassCategory, detect_land_cover_change,
5
+ sample_constant, sample_plus_minus_error
6
+ )
7
+
8
+ _ITERATIONS = 1000
9
+
10
+
11
+ # input, expected
12
+ PARAMS_RESCALE_CATEGORY_COVER = [
13
+ (
14
+ {BiomassCategory.ANNUAL_CROPS: 90},
15
+ {BiomassCategory.ANNUAL_CROPS: 90, BiomassCategory.OTHER: 10}
16
+ ),
17
+ (
18
+ {BiomassCategory.OTHER: 90},
19
+ {BiomassCategory.OTHER: 100}
20
+ ),
21
+ (
22
+ {BiomassCategory.ANNUAL_CROPS: 60, BiomassCategory.VINE: 60},
23
+ {BiomassCategory.ANNUAL_CROPS: 50, BiomassCategory.VINE: 50}
24
+ ),
25
+ (
26
+ {BiomassCategory.NATURAL_FOREST: 100},
27
+ {BiomassCategory.NATURAL_FOREST: 100}
28
+ )
29
+ ]
30
+ IDS_RESCALE_CATEGORY_COVER = ["fill", "fill w/ other", "squash", "do nothing"]
31
+
32
+
33
+ @mark.parametrize("input, expected", PARAMS_RESCALE_CATEGORY_COVER, ids=IDS_RESCALE_CATEGORY_COVER)
34
+ def test_rescale_category_cover(input: dict, expected: dict):
35
+ assert _rescale_category_cover(input) == expected
36
+
37
+
38
+ # a, b, expected
39
+ PARAMS_IS_LCC_EVENT = [
40
+ (
41
+ {
42
+ "appleTree": 33.333,
43
+ "pearTree": 33.333,
44
+ BiomassCategory.ANNUAL_CROPS: 33.334,
45
+ },
46
+ {
47
+ "appleTree": 33.33333,
48
+ "pearTree": 33.33333,
49
+ BiomassCategory.ANNUAL_CROPS: 33.33334,
50
+ },
51
+ True
52
+ ),
53
+ (
54
+ {
55
+ "appleTree": 33.3333,
56
+ "pearTree": 33.3333,
57
+ BiomassCategory.ANNUAL_CROPS: 33.3334,
58
+ },
59
+ {
60
+ "appleTree": 33.33333,
61
+ "pearTree": 33.33333,
62
+ BiomassCategory.ANNUAL_CROPS: 33.33334,
63
+ },
64
+ False
65
+ )
66
+ ]
67
+ IDS_IS_LCC_EVENT = ["True", "False"]
68
+
69
+
70
+ @mark.parametrize("a, b, expected", PARAMS_IS_LCC_EVENT, ids=IDS_IS_LCC_EVENT)
71
+ def test_detect_land_cover_change(a: dict, b: dict, expected: bool):
72
+ assert detect_land_cover_change(a, b) is expected
73
+
74
+
75
+ # kwargs, sample_func, expected_shape
76
+ PARAMS_GET_SAMPLE_FUNC = [
77
+ ({"value": 1}, sample_constant),
78
+ ({"value": 1, "error": 10}, sample_plus_minus_error),
79
+ ]
80
+ IDS_GET_SAMPLE_FUNC = ["constant", "+/- error"]
81
+
82
+
83
+ @mark.parametrize("kwargs, sample_func", PARAMS_GET_SAMPLE_FUNC, ids=IDS_GET_SAMPLE_FUNC)
84
+ def test_get_sample_func(kwargs, sample_func):
85
+ result = _get_sample_func(kwargs)
86
+ assert result == sample_func
87
+
88
+
89
+ # input, expected
90
+ PARAMS_ASSIGN_BIOMASS_CATEGORY = [
91
+ ("Annual crops", BiomassCategory.ANNUAL_CROPS),
92
+ ("Coconut", BiomassCategory.COCONUT),
93
+ ("Forest", BiomassCategory.FOREST),
94
+ ("Grassland", BiomassCategory.GRASSLAND),
95
+ ("Jatropha", BiomassCategory.JATROPHA),
96
+ ("Jojoba", BiomassCategory.JOJOBA),
97
+ ("Natural forest", BiomassCategory.NATURAL_FOREST),
98
+ ("Oil palm", BiomassCategory.OIL_PALM),
99
+ ("Olive", BiomassCategory.OLIVE),
100
+ ("Orchard", BiomassCategory.ORCHARD),
101
+ ("Other", BiomassCategory.OTHER),
102
+ ("Plantation forest", BiomassCategory.PLANTATION_FOREST),
103
+ ("Rubber", BiomassCategory.RUBBER),
104
+ ("Short rotation coppice", BiomassCategory.SHORT_ROTATION_COPPICE),
105
+ ("Tea", BiomassCategory.TEA),
106
+ ("Vine", BiomassCategory.VINE),
107
+ ("Woody perennial", BiomassCategory.WOODY_PERENNIAL),
108
+ ("Miscellaneous value", None)
109
+ ]
110
+ IDS_ASSIGN_BIOMASS_CATEGORY = [p[0] for p in PARAMS_ASSIGN_BIOMASS_CATEGORY]
111
+
112
+
113
+ @mark.parametrize("input, expected", PARAMS_ASSIGN_BIOMASS_CATEGORY, ids=IDS_ASSIGN_BIOMASS_CATEGORY)
114
+ def test_assign_biomass_category(input: str, expected: BiomassCategory):
115
+ assert _assign_biomass_category(input) == expected
@@ -4,13 +4,13 @@ from os.path import isfile
4
4
  from pytest import mark
5
5
  from unittest.mock import patch
6
6
 
7
- from hestia_earth.models.ipcc2019.co2ToAirAboveGroundBiomassStockChangeLandUseChange import MODEL, run, TERM_ID
7
+ from hestia_earth.models.ipcc2019.co2ToAirAboveGroundBiomassStockChange import MODEL, run
8
8
 
9
- from tests.utils import fake_new_emission, fixtures_path
9
+ from tests.utils import fake_new_emission, fixtures_path, order_list
10
10
 
11
- class_path = f"hestia_earth.models.{MODEL}.{TERM_ID}"
11
+ class_path = f"hestia_earth.models.{MODEL}.co2ToAirAboveGroundBiomassStockChange"
12
12
  utils_path = f"hestia_earth.models.{MODEL}.co2ToAirCarbonStockChange_utils"
13
- fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
13
+ fixtures_folder = f"{fixtures_path}/{MODEL}/co2ToAirAboveGroundBiomassStockChange"
14
14
 
15
15
  RUN_SCENARIOS = [
16
16
  ("no-overlapping-cycles", 3),
@@ -63,7 +63,7 @@ def test_run(_get_site_mock, related_cycles_mock, _new_emission_mock, subfolder,
63
63
  related_cycles_mock.return_value = cycles
64
64
 
65
65
  result = run(cycle)
66
- assert result == expected
66
+ assert order_list(result) == order_list(expected)
67
67
 
68
68
 
69
69
  @patch(f"{class_path}._new_emission", side_effect=fake_new_emission)
@@ -4,13 +4,13 @@ from os.path import isfile
4
4
  from pytest import mark
5
5
  from unittest.mock import patch
6
6
 
7
- from hestia_earth.models.ipcc2019.co2ToAirBelowGroundBiomassStockChangeLandUseChange import MODEL, run, TERM_ID
7
+ from hestia_earth.models.ipcc2019.co2ToAirBelowGroundBiomassStockChange import MODEL, run
8
8
 
9
- from tests.utils import fake_new_emission, fixtures_path
9
+ from tests.utils import fake_new_emission, fixtures_path, order_list
10
10
 
11
- class_path = f"hestia_earth.models.{MODEL}.{TERM_ID}"
11
+ class_path = f"hestia_earth.models.{MODEL}.co2ToAirBelowGroundBiomassStockChange"
12
12
  utils_path = f"hestia_earth.models.{MODEL}.co2ToAirCarbonStockChange_utils"
13
- fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
13
+ fixtures_folder = f"{fixtures_path}/{MODEL}/co2ToAirBelowGroundBiomassStockChange"
14
14
 
15
15
  RUN_SCENARIOS = [
16
16
  ("no-overlapping-cycles", 3),
@@ -63,7 +63,7 @@ def test_run(_get_site_mock, related_cycles_mock, _new_emission_mock, subfolder,
63
63
  related_cycles_mock.return_value = cycles
64
64
 
65
65
  result = run(cycle)
66
- assert result == expected
66
+ assert order_list(result) == order_list(expected)
67
67
 
68
68
 
69
69
  @patch(f"{class_path}._new_emission", side_effect=fake_new_emission)
@@ -4,13 +4,13 @@ from os.path import isfile
4
4
  from pytest import mark
5
5
  from unittest.mock import patch
6
6
 
7
- from hestia_earth.models.ipcc2019.co2ToAirSoilOrganicCarbonStockChangeManagementChange import MODEL, run, TERM_ID
7
+ from hestia_earth.models.ipcc2019.co2ToAirSoilOrganicCarbonStockChange import MODEL, run
8
8
 
9
- from tests.utils import fake_new_emission, fixtures_path
9
+ from tests.utils import fake_new_emission, fixtures_path, order_list
10
10
 
11
- class_path = f"hestia_earth.models.{MODEL}.{TERM_ID}"
11
+ class_path = f"hestia_earth.models.{MODEL}.co2ToAirSoilOrganicCarbonStockChange"
12
12
  utils_path = f"hestia_earth.models.{MODEL}.co2ToAirCarbonStockChange_utils"
13
- fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
13
+ fixtures_folder = f"{fixtures_path}/{MODEL}/co2ToAirSoilOrganicCarbonStockChange"
14
14
 
15
15
  RUN_SCENARIOS = [
16
16
  ("no-overlapping-cycles", 3),
@@ -63,7 +63,7 @@ def test_run(_get_site_mock, related_cycles_mock, _new_emission_mock, subfolder,
63
63
  related_cycles_mock.return_value = cycles
64
64
 
65
65
  result = run(cycle)
66
- assert result == expected
66
+ assert order_list(result) == order_list(expected)
67
67
 
68
68
 
69
69
  @patch(f"{class_path}._new_emission", side_effect=fake_new_emission)
@@ -13,8 +13,8 @@ def test_run_no_emissions():
13
13
  impact = json.load(f)
14
14
 
15
15
  impact['emissionsResourceUse'] = []
16
- value = run(impact)
17
- assert value is None
16
+ indicator = run(impact)
17
+ assert indicator.get('value') == 0
18
18
 
19
19
 
20
20
  @patch(f"{class_path}._new_indicator", side_effect=fake_new_indicator)
@@ -1,7 +1,7 @@
1
- from hestia_earth.models.utils.impact_assessment import impact_lookup_value, get_region_id
1
+ from hestia_earth.models.utils.impact_assessment import impact_emission_lookup_value, get_region_id
2
2
 
3
3
 
4
- def test_impact_lookup_value():
4
+ def test_impact_emission_lookup_value():
5
5
  impact = {
6
6
  'emissionsResourceUse': [
7
7
  {
@@ -14,7 +14,7 @@ def test_impact_lookup_value():
14
14
  ]
15
15
  }
16
16
  # multiplies the emissionsResourceUse values with a coefficient
17
- assert impact_lookup_value('', '', impact, 'co2EqGwp100ExcludingClimate-CarbonFeedbacksIpcc2013') == 2800
17
+ assert impact_emission_lookup_value('', '', impact, 'co2EqGwp100ExcludingClimate-CarbonFeedbacksIpcc2013') == 2800
18
18
 
19
19
 
20
20
  def test_get_region_id():
@@ -1,180 +0,0 @@
1
- from enum import Enum
2
- from numpy import random
3
- from numpy.typing import NDArray
4
- from typing import Callable, Optional, Union
5
-
6
- from hestia_earth.models.utils.array_builders import repeat_single, truncated_normal_1d
7
- from hestia_earth.models.utils.ecoClimateZone import EcoClimateZone, get_ecoClimateZone_lookup_grouped_value
8
-
9
-
10
- class BiomassCategory(Enum):
11
- """
12
- Enum representing biomass categories, sourced from IPCC (2006), IPCC (2019) and European Commission (2010).
13
-
14
- Enum values formatted for logging as table.
15
- """
16
- ANNUAL_CROPS = "annual-crops"
17
- COCONUT = "coconut" # European Commission (2010)
18
- FOREST = "forest" # IPCC (2019) recalculated per eco-climate zone
19
- GRASSLAND = "grassland"
20
- JATROPHA = "jatropha" # European Commission (2010)
21
- JOJOBA = "jojoba" # European Commission (2010)
22
- NATURAL_FOREST = "natural-forest" # IPCC (2019) recalculated per eco-climate zone
23
- OIL_PALM = "oil palm" # IPCC (2019)
24
- OLIVE = "olive" # IPCC (2019)
25
- ORCHARD = "orchard" # IPCC (2019)
26
- OTHER = "other"
27
- PLANTATION_FOREST = "plantation-forest" # IPCC (2019) recalculated per eco-climate zone
28
- RUBBER = "rubber" # IPCC (2019)
29
- SHORT_ROTATION_COPPICE = "short-rotation-coppice" # IPCC (2019)
30
- TEA = "tea" # IPCC (2019)
31
- VINE = "vine" # IPCC (2019)
32
- WOODY_PERENNIAL = "woody-perennial" # IPCC (2006)
33
-
34
-
35
- BIOMASS_CATEGORY_TO_LAND_COVER_LOOKUP_VALUE = {
36
- BiomassCategory.ANNUAL_CROPS: "Annual crops",
37
- BiomassCategory.COCONUT: "Coconut",
38
- BiomassCategory.FOREST: "Forest",
39
- BiomassCategory.GRASSLAND: "Grassland",
40
- BiomassCategory.JATROPHA: "Jatropha",
41
- BiomassCategory.JOJOBA: "Jojoba",
42
- BiomassCategory.NATURAL_FOREST: "Natural forest",
43
- BiomassCategory.OIL_PALM: "Oil palm",
44
- BiomassCategory.OLIVE: "Olive",
45
- BiomassCategory.ORCHARD: "Orchard",
46
- BiomassCategory.OTHER: "Other",
47
- BiomassCategory.PLANTATION_FOREST: "Plantation forest",
48
- BiomassCategory.RUBBER: "Rubber",
49
- BiomassCategory.SHORT_ROTATION_COPPICE: "Short rotation coppice",
50
- BiomassCategory.TEA: "Tea",
51
- BiomassCategory.VINE: "Vine",
52
- BiomassCategory.WOODY_PERENNIAL: "Woody perennial"
53
- }
54
-
55
-
56
- def assign_biomass_category(lookup_value: str) -> BiomassCategory:
57
- """
58
- Return the `BiomassCategory` enum member associated with the input lookup value. If lookup value is missing or
59
- doesn't map to any category, return `None`.
60
- """
61
- return next(
62
- (key for key, value in BIOMASS_CATEGORY_TO_LAND_COVER_LOOKUP_VALUE.items() if value == lookup_value),
63
- None
64
- )
65
-
66
-
67
- def sample_biomass_equilibrium(
68
- iterations: int,
69
- biomass_category: BiomassCategory,
70
- eco_climate_zone: EcoClimateZone,
71
- seed: Union[int, random.Generator, None] = None
72
- ) -> dict:
73
- """
74
- Sample a biomass equilibrium using the function specified in `KWARGS_TO_SAMPLE_FUNC`.
75
-
76
- Parameters
77
- ----------
78
- iterations : int
79
- The number of samples to take.
80
- biomass_category : BiomassCategory
81
- The biomass category of the land cover.
82
- eco_climate_zone : EcoClimateZone
83
- The eco-climate zone of the site.
84
- seed : int | Generator | None, optional
85
- A seed to initialize the BitGenerator. If passed a Generator, it will be returned unaltered. If `None`, then
86
- fresh, unpredictable entropy will be pulled from the OS.
87
-
88
- Returns
89
- -------
90
- NDArray
91
- The sampled parameter as a numpy array with shape `(1, iterations)`.
92
- """
93
- kwargs = _get_biomass_equilibrium(biomass_category, eco_climate_zone)
94
- func = _get_sample_func(kwargs)
95
- return func(iterations=iterations, seed=seed, **kwargs)
96
-
97
-
98
- def _get_biomass_equilibrium(biomass_category: BiomassCategory, eco_climate_zone: EcoClimateZone) -> dict:
99
- """
100
- Retrieve the biomass equilibrium data for a specific combination of biomass category and eco-climate zone.
101
-
102
- Parameters
103
- ----------
104
- biomass_category : BiomassCategory
105
- The biomass category of the land cover.
106
- eco_climate_zone : EcoClimateZone
107
- The eco-climate zone of the site.
108
-
109
- Returns
110
- -------
111
- dict
112
- The biomass equilibrium data.
113
- """
114
- return get_ecoClimateZone_lookup_grouped_value(
115
- eco_climate_zone.value,
116
- _build_col_name(biomass_category),
117
- default={"value": 0}
118
- )
119
-
120
-
121
- def _build_col_name(biomass_category: BiomassCategory) -> str:
122
- """
123
- Get the column name for the `ecoClimateZone-lookup.csv` for a specific biomass category equilibrium.
124
- """
125
- COL_NAME_ROOT = "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_"
126
- return (
127
- f"{COL_NAME_ROOT}{biomass_category.name}" if isinstance(biomass_category, BiomassCategory)
128
- else f"{COL_NAME_ROOT}OTHER"
129
- )
130
-
131
-
132
- def _get_sample_func(kwargs: dict) -> Callable:
133
- """
134
- Select the correct sample function for a parameter based on the distribution data available. All possible
135
- parameters for the model should have, at a minimum, a `value`, meaning that no default function needs to be
136
- specified.
137
-
138
- This function has been extracted into it's own method to allow for mocking of sample function.
139
-
140
- Keyword Args
141
- ------------
142
- value : float
143
- The distribution mean.
144
- sd : float
145
- The standard deviation of the distribution.
146
- uncertainty : float
147
- The +/- uncertainty of the 95% confidence interval expressed as a percentage of the mean.
148
- error : float
149
- Two standard deviations expressed as a percentage of the mean.
150
-
151
- Returns
152
- -------
153
- Callable
154
- The sample function for the distribution.
155
- """
156
- return next(
157
- sample_func for required_kwargs, sample_func in _KWARGS_TO_SAMPLE_FUNC.items()
158
- if all(kwarg in kwargs.keys() for kwarg in required_kwargs)
159
- )
160
-
161
-
162
- def sample_plus_minus_error(
163
- *, iterations: int, value: float, error: float, seed: Optional[int] = None, **_
164
- ) -> NDArray:
165
- """Randomly sample a model parameter with a truncated normal distribution described using plus/minus error."""
166
- sd = value * (error / 200)
167
- low = value - (value * (error / 100))
168
- high = value + (value * (error / 100))
169
- return truncated_normal_1d(shape=(1, iterations), mu=value, sigma=sd, low=low, high=high, seed=seed)
170
-
171
-
172
- def sample_constant(*, iterations: int, value: float, **_) -> NDArray:
173
- """Sample a constant model parameter."""
174
- return repeat_single(shape=(1, iterations), value=value)
175
-
176
-
177
- _KWARGS_TO_SAMPLE_FUNC = {
178
- ("value", "error"): sample_plus_minus_error,
179
- ("value",): sample_constant
180
- }
@@ -1,92 +0,0 @@
1
- from pytest import mark
2
-
3
- from itertools import product
4
- from hestia_earth.models.ipcc2019.aboveGroundBiomass_utils import (
5
- _build_col_name, _get_sample_func, assign_biomass_category, BiomassCategory, EcoClimateZone,
6
- sample_biomass_equilibrium, sample_constant, sample_plus_minus_error
7
- )
8
-
9
- _ITERATIONS = 1000
10
-
11
-
12
- # kwargs, sample_func, expected_shape
13
- PARAMS_GET_SAMPLE_FUNC = [
14
- ({"value": 1}, sample_constant),
15
- ({"value": 1, "error": 10}, sample_plus_minus_error),
16
- ]
17
- IDS_GET_SAMPLE_FUNC = ["constant", "+/- error"]
18
-
19
-
20
- @mark.parametrize("kwargs, sample_func", PARAMS_GET_SAMPLE_FUNC, ids=IDS_GET_SAMPLE_FUNC)
21
- def test_get_sample_func(kwargs, sample_func):
22
- result = _get_sample_func(kwargs)
23
- assert result == sample_func
24
-
25
-
26
- PARAMS_BIOMASS = [p for p in product(BiomassCategory, EcoClimateZone)]
27
- IDS_BIOMASS = [f"{p[0].name} + {p[1].name}" for p in PARAMS_BIOMASS]
28
-
29
-
30
- @mark.parametrize("biomass_category, eco_climate_zone", PARAMS_BIOMASS, ids=IDS_BIOMASS)
31
- def test_sample_biomass_equilibrium(biomass_category, eco_climate_zone):
32
- EXPECTED_SHAPE = (1, _ITERATIONS)
33
- result = sample_biomass_equilibrium(_ITERATIONS, biomass_category, eco_climate_zone)
34
- assert result.shape == EXPECTED_SHAPE
35
-
36
-
37
- # input, expected
38
- PARAMS_ASSIGN_BIOMASS_CATEGORY = [
39
- ("Annual crops", BiomassCategory.ANNUAL_CROPS),
40
- ("Coconut", BiomassCategory.COCONUT),
41
- ("Forest", BiomassCategory.FOREST),
42
- ("Grassland", BiomassCategory.GRASSLAND),
43
- ("Jatropha", BiomassCategory.JATROPHA),
44
- ("Jojoba", BiomassCategory.JOJOBA),
45
- ("Natural forest", BiomassCategory.NATURAL_FOREST),
46
- ("Oil palm", BiomassCategory.OIL_PALM),
47
- ("Olive", BiomassCategory.OLIVE),
48
- ("Orchard", BiomassCategory.ORCHARD),
49
- ("Other", BiomassCategory.OTHER),
50
- ("Plantation forest", BiomassCategory.PLANTATION_FOREST),
51
- ("Rubber", BiomassCategory.RUBBER),
52
- ("Short rotation coppice", BiomassCategory.SHORT_ROTATION_COPPICE),
53
- ("Tea", BiomassCategory.TEA),
54
- ("Vine", BiomassCategory.VINE),
55
- ("Woody perennial", BiomassCategory.WOODY_PERENNIAL),
56
- ("Miscellaneous value", None)
57
- ]
58
- IDS_ASSIGN_BIOMASS_CATEGORY = [p[0] for p in PARAMS_ASSIGN_BIOMASS_CATEGORY]
59
-
60
-
61
- @mark.parametrize("input, expected", PARAMS_ASSIGN_BIOMASS_CATEGORY, ids=IDS_ASSIGN_BIOMASS_CATEGORY)
62
- def test_assign_biomass_category(input: str, expected: BiomassCategory):
63
- assert assign_biomass_category(input) == expected
64
-
65
-
66
- # input, expected
67
- PARAMS_BUILD_COLUMN_NAME = [
68
- (BiomassCategory.ANNUAL_CROPS, "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_ANNUAL_CROPS"),
69
- (BiomassCategory.COCONUT, "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_COCONUT"),
70
- (BiomassCategory.FOREST, "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_FOREST"),
71
- (BiomassCategory.GRASSLAND, "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_GRASSLAND"),
72
- (BiomassCategory.JATROPHA, "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_JATROPHA"),
73
- (BiomassCategory.JOJOBA, "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_JOJOBA"),
74
- (BiomassCategory.NATURAL_FOREST, "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_NATURAL_FOREST"),
75
- (BiomassCategory.OIL_PALM, "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_OIL_PALM"),
76
- (BiomassCategory.OLIVE, "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_OLIVE"),
77
- (BiomassCategory.ORCHARD, "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_ORCHARD"),
78
- (BiomassCategory.OTHER, "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_OTHER"),
79
- (BiomassCategory.PLANTATION_FOREST, "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_PLANTATION_FOREST"),
80
- (BiomassCategory.RUBBER, "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_RUBBER"),
81
- (BiomassCategory.SHORT_ROTATION_COPPICE, "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_SHORT_ROTATION_COPPICE"),
82
- (BiomassCategory.TEA, "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_TEA"),
83
- (BiomassCategory.VINE, "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_VINE"),
84
- (BiomassCategory.WOODY_PERENNIAL, "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_WOODY_PERENNIAL"),
85
- ("Miscellaneous value", "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_OTHER")
86
- ]
87
- IDS_BUILD_COLUMN_NAME = [p[0] for p in PARAMS_BUILD_COLUMN_NAME]
88
-
89
-
90
- @mark.parametrize("input, expected", PARAMS_BUILD_COLUMN_NAME, ids=IDS_BUILD_COLUMN_NAME)
91
- def test_build_col_name(input: BiomassCategory, expected: str):
92
- assert _build_col_name(input) == expected