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,196 @@
1
+ import json
2
+ from unittest.mock import patch
3
+
4
+ from pytest import mark
5
+
6
+ from hestia_earth.models.cml2001Baseline.abioticResourceDepletionFossilFuels import MODEL, TERM_ID, run, _should_run, \
7
+ download_all_non_renewable_terms
8
+ from tests.utils import fixtures_path, fake_new_indicator
9
+
10
+ class_path = f"hestia_earth.models.{MODEL}.{TERM_ID}"
11
+ fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
12
+
13
+
14
+ def fake_rounded_indicator(value: float):
15
+ indicator = fake_new_indicator(TERM_ID, MODEL)
16
+ indicator['value'] = round(value, 7)
17
+ return indicator
18
+
19
+
20
+ def fake_download_hestia(filename):
21
+ data = {
22
+ 'fuel.csv': ["lignite", "conventionalCrudeOil", "naturalGas", "coalTar"],
23
+ 'electricity.csv': ['electricityGridMarketMix', 'electricityGridHardCoal', 'electricityProducedOnSiteHardCoal',
24
+ 'electricityGridNaturalGas', 'electricityProducedOnSiteNaturalGas', 'electricityGridOil',
25
+ 'electricityProducedOnSiteOil', 'electricityGridNuclear']}
26
+ return data[filename]
27
+
28
+
29
+ input_lignite_mj = {"@id": "lignite", "name": "lignite (Brown coal)", "termType": "fuel", "units": "MJ"}
30
+ input_coal_tar_kg = {"@id": "coalTar", "name": "Coal tar unknown energy Content", "termType": "fuel", "units": "kg"}
31
+ input_crude_oil_kg_property = {
32
+ "@id": "conventionalCrudeOil", "name": "Conventional Crude Oil", "termType": "fuel", "units": "kg",
33
+ "properties": [{"@type": "Property", "value": 45.8,
34
+ "term": {"@type": "Term", "@id": "energyContentHigherHeatingValue", "units": "MJ / kg"}, }]}
35
+ input_crude_oil_kg_no_property = {
36
+ "@id": "conventionalCrudeOil", "name": "Conventional Crude Oil", "termType": "fuel", "units": "kg"}
37
+ input_natural_gas_m3 = {"@id": "naturalGas", "name": "Natural Gas", "termType": "fuel", "units": "m3"}
38
+ input_nuclear_fuel_mj = {"@id": "electricityGridNuclear", "name": "Any depleted nuclear fuel",
39
+ "termType": "electricity", "units": "MJ"}
40
+ input_nuclear_fuel_kwh = {"@id": "electricityGridNuclear", "termType": "electricity", "units": "kWh"}
41
+ input_excessIndustrialHeat_mj = {"@id": "excessIndustrialHeat", "name": "Excess industrial heat", "termType": "fuel",
42
+ "units": "MJ"}
43
+
44
+ wrong_indicator = {"term": {"@id": "BAD_INDICATOR_ID", "termType": "resourceUse"},
45
+ "value": 5,
46
+ "inputs": [input_lignite_mj]}
47
+
48
+ indicator_no_inputs = {"term": {"@id": "resourceUseEnergyDepletionInputsProduction", "termType": "resourceUse"},
49
+ "value": 5,
50
+ "inputs": []}
51
+
52
+ indicator_2_inputs = {"term": {"@id": "resourceUseEnergyDepletionInputsProduction", "termType": "resourceUse"},
53
+ "value": 5,
54
+ "inputs": [input_lignite_mj, input_lignite_mj]}
55
+
56
+ indicator_no_unit = {"term": {"@id": "resourceUseEnergyDepletionInputsProduction", "termType": "resourceUse"},
57
+ "value": 5,
58
+ "inputs": [{
59
+ "@id": "lignite",
60
+ "@type": "Term",
61
+ "name": "lignite (Brown coal)",
62
+ "termType": "fuel",
63
+ }]}
64
+
65
+ indicator_wrong_unit = {"term": {"@id": "resourceUseEnergyDepletionInputsProduction", "termType": "resourceUse"},
66
+ "value": 5,
67
+ "inputs": [
68
+ {
69
+ "@id": "lignite",
70
+ "@type": "Term",
71
+ "name": "lignite (Brown coal)",
72
+ "termType": "fuel",
73
+ "units": "ha"
74
+ }
75
+ ]}
76
+
77
+ indicator_bad_input_id = {"term": {"@id": "resourceUseEnergyDepletionInputsProduction", "termType": "resourceUse"},
78
+ "value": 5,
79
+ "inputs": [input_excessIndustrialHeat_mj]}
80
+
81
+ good_indicator_inputs_production_mj = {
82
+ "term": {"@id": "resourceUseEnergyDepletionInputsProduction", "termType": "resourceUse"},
83
+ "value": 5,
84
+ "inputs": [input_lignite_mj]
85
+ }
86
+
87
+ good_indicator_during_cycle_mj = {"term": {"@id": "resourceUseEnergyDepletionDuringCycle", "termType": "resourceUse"},
88
+ "value": 5,
89
+ "inputs": [input_lignite_mj]}
90
+
91
+ good_indicator_inputs_production_with_property = {
92
+ "term": {"@id": "resourceUseEnergyDepletionInputsProduction", "termType": "resourceUse"},
93
+ "value": 5,
94
+ "inputs": [input_crude_oil_kg_property]
95
+ }
96
+
97
+ good_indicator_inputs_production_with_no_property = {
98
+ "term": {"@id": "resourceUseEnergyDepletionInputsProduction", "termType": "resourceUse"},
99
+ "value": 5,
100
+ "inputs": [input_crude_oil_kg_no_property]
101
+ }
102
+
103
+ good_indicator_m3 = {"term": {"@id": "resourceUseEnergyDepletionInputsProduction", "termType": "resourceUse"},
104
+ "value": 5,
105
+ "inputs": [input_natural_gas_m3]}
106
+
107
+ good_nuclear_indicator_mj = {"term": {"@id": "resourceUseEnergyDepletionInputsProduction", "termType": "resourceUse"},
108
+ "value": 5,
109
+ "inputs": [input_nuclear_fuel_mj]}
110
+ good_nuclear_indicator_kwh = {"term": {"@id": "resourceUseEnergyDepletionInputsProduction", "termType": "resourceUse"},
111
+ "value": 1.3889,
112
+ "inputs": [input_nuclear_fuel_kwh]}
113
+
114
+ bad_fuel_indicator_no_property_lookup = {
115
+ "term": {"@id": "resourceUseEnergyDepletionInputsProduction", "termType": "resourceUse"},
116
+ "value": 5,
117
+ "inputs": [input_coal_tar_kg]}
118
+
119
+
120
+ @mark.parametrize(
121
+ "resources, expected, num_inputs",
122
+ [
123
+ ([], True, 0),
124
+ ([wrong_indicator], True, 0),
125
+ ([indicator_no_inputs], False, 0),
126
+ ([indicator_2_inputs], False, 2),
127
+ ([indicator_no_unit], False, 0),
128
+ ([indicator_wrong_unit], False, 0),
129
+ ([indicator_bad_input_id], False, 0),
130
+ ([good_indicator_inputs_production_mj], True, 1),
131
+ ([good_indicator_during_cycle_mj], True, 1),
132
+ ([good_indicator_inputs_production_with_property], True, 1),
133
+ ([good_indicator_inputs_production_with_no_property], True, 1),
134
+ ([good_indicator_m3], True, 1),
135
+ ([good_nuclear_indicator_mj], True, 1),
136
+ ([good_nuclear_indicator_kwh], True, 1),
137
+ ([bad_fuel_indicator_no_property_lookup], False, 0),
138
+ ],
139
+ ids=["No indicators", "wrong indicator", "indicator no inputs", "indicator 2 inputs", "missing unit", "wrong unit",
140
+ "input id not in requirements", "good input production mj", "good during cycle mj",
141
+ "good input with input property", "good input with no input property", "good indicator in m^3",
142
+ "good nuclear fuel use indicator in mj", "good nuclear fuel use indicator in kWh",
143
+ "bad indicator input in kg no property to convert to mj"]
144
+ )
145
+ @patch(f"{class_path}.download_all_non_renewable_terms", side_effect=fake_download_hestia)
146
+ def test_should_run(mock_download_all_non_renewable_terms, resources, expected, num_inputs):
147
+ with open(f"{fixtures_folder}/impactassessment.jsonld", encoding='utf-8') as f:
148
+ impactassessment = json.load(f)
149
+
150
+ impactassessment['emissionsResourceUse'] = resources
151
+
152
+ should_run, resources = _should_run(impactassessment)
153
+ assert should_run is expected
154
+ assert len(resources) == num_inputs
155
+
156
+
157
+ @patch(f"{class_path}.download_all_non_renewable_terms", side_effect=fake_download_hestia)
158
+ @patch(f"{class_path}._indicator", side_effect=fake_rounded_indicator)
159
+ def test_run(*args):
160
+ with open(f"{fixtures_folder}/impactassessment.jsonld", encoding='utf-8') as f:
161
+ impactassessment = json.load(f)
162
+
163
+ with open(f"{fixtures_folder}/result.jsonld", encoding='utf-8') as f:
164
+ expected = json.load(f)
165
+
166
+ value = run(impactassessment)
167
+ assert value == expected
168
+
169
+
170
+ @patch(f"{class_path}._new_indicator", side_effect=fake_new_indicator)
171
+ def test_run_no_emissions(*args):
172
+ """
173
+ Impact assessment with no emissions should return a indicator of 0
174
+ """
175
+ with open(f"{fixtures_folder}/impactassessment.jsonld", encoding='utf-8') as f:
176
+ impactassessment = json.load(f)
177
+
178
+ del impactassessment['emissionsResourceUse']
179
+
180
+ value = run(impactassessment)
181
+ assert value['value'] == 0
182
+
183
+
184
+ def test_download_all_non_renewable_terms(*args):
185
+ """
186
+ make sure download_all_non_renewable_terms() only returns terms we want
187
+ """
188
+ electricity_terms = download_all_non_renewable_terms("electricity.csv")
189
+
190
+ assert "electricityGridHardCoal" in electricity_terms
191
+ assert "electricityGridWind" not in electricity_terms
192
+
193
+ fuel_terms = download_all_non_renewable_terms("fuel.csv")
194
+
195
+ assert "coalTar" in fuel_terms
196
+ assert "sodPeat" not in fuel_terms
@@ -0,0 +1,124 @@
1
+ import json
2
+ from unittest.mock import patch
3
+
4
+ from pytest import mark
5
+
6
+ from hestia_earth.models.cml2001Baseline.abioticResourceDepletionMineralsAndMetals import MODEL, TERM_ID, run, \
7
+ _should_run
8
+ from tests.utils import fixtures_path, fake_new_indicator
9
+
10
+ class_path = f"hestia_earth.models.{MODEL}.{TERM_ID}"
11
+ fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
12
+
13
+
14
+ def fake_rounded_indicator(value: float):
15
+ indicator = fake_new_indicator(TERM_ID, MODEL)
16
+ indicator['value'] = round(value, 7)
17
+ return indicator
18
+
19
+
20
+ iodine_input = {"@id": "iodineMaterial", "termType": "material", "units": "kg"}
21
+ boron_input = {"@id": "boron", "termType": "soilAmendment", "units": "kg B"}
22
+ tellurium_input = {"@id": "CAS-13494-80-9", "termType": "otherInorganicChemical", "units": "kg"}
23
+ input_no_cf_material = {"@id": "cork", "termType": "material", "units": "kg"}
24
+
25
+ wrong_indicator = {'value': [1],
26
+ 'term': {'@id': 'landTransformationFromCropland20YearAverageDuringCycle', 'termType': 'resourceUse'},
27
+ 'inputs': [iodine_input]}
28
+
29
+ indicator_no_inputs = {'value': 3,
30
+ 'term': {'@id': 'resourceUseMineralsAndMetalsInputsProduction', 'termType': 'resourceUse'},
31
+ 'inputs': []}
32
+ indicator_2_inputs = {
33
+ 'value': 3, 'term': {'@id': 'resourceUseMineralsAndMetalsInputsProduction', 'termType': 'resourceUse'},
34
+ 'inputs': [boron_input, iodine_input]
35
+ }
36
+
37
+ indicator_no_unit = {
38
+ 'value': 3, 'term': {'@id': 'resourceUseMineralsAndMetalsInputsProduction', 'termType': 'resourceUse'},
39
+ 'inputs': [{"@id": "iodineMaterial", "termType": "material", }],
40
+ }
41
+
42
+ indicator_wrong_unit = {
43
+ 'value': 3, 'term': {'@id': 'resourceUseMineralsAndMetalsInputsProduction', 'termType': 'resourceUse'},
44
+ 'inputs': [{"@id": "iodineMaterial", "termType": "material", "units": "Mj"}],
45
+ }
46
+
47
+ indicator_no_cf_material = {
48
+ 'value': 3, 'term': {'@id': 'resourceUseMineralsAndMetalsInputsProduction', 'termType': 'resourceUse'},
49
+ 'inputs': [input_no_cf_material]
50
+ }
51
+
52
+ indicator_iodine = {
53
+ 'value': [1],
54
+ 'term': {'@id': 'resourceUseMineralsAndMetalsInputsProduction', 'termType': 'resourceUse'},
55
+ 'inputs': [iodine_input]
56
+ }
57
+
58
+ indicator_boron = {
59
+ 'value': 2,
60
+ 'term': {'@id': 'resourceUseMineralsAndMetalsInputsProduction', 'termType': 'resourceUse'},
61
+ 'inputs': [boron_input]
62
+ }
63
+
64
+ indicator_tellurium = {
65
+ 'value': 2,
66
+ 'term': {'@id': 'resourceUseMineralsAndMetalsInputsProduction', 'termType': 'resourceUse'},
67
+ 'inputs': [tellurium_input]
68
+ }
69
+
70
+
71
+ @mark.parametrize(
72
+ "resources, expected, num_inputs",
73
+ [
74
+ ([], True, 0),
75
+ ([wrong_indicator], True, 0),
76
+ ([indicator_no_inputs], False, 0),
77
+ ([indicator_2_inputs], False, 0),
78
+ ([indicator_no_unit], False, 0),
79
+ ([indicator_wrong_unit], False, 0),
80
+ ([indicator_no_cf_material], True, 0),
81
+ ([indicator_iodine], True, 1),
82
+ ([indicator_boron], True, 1),
83
+ ([indicator_tellurium], True, 1),
84
+ ([indicator_iodine, indicator_no_cf_material], True, 1),
85
+ ],
86
+ ids=["No indicators", "wrong indicator", "indicator no inputs", "indicator 2 inputs", "missing unit", "wrong unit",
87
+ "material with no cf", "good input material", "good input soilAmendment", "good input otherInorganicChemical",
88
+ "one good input"]
89
+ )
90
+ def test_should_run(resources, expected, num_inputs):
91
+ with open(f"{fixtures_folder}/impactassessment.jsonld", encoding='utf-8') as f:
92
+ impactassessment = json.load(f)
93
+
94
+ impactassessment['emissionsResourceUse'] = resources
95
+
96
+ should_run, grouped_inputs = _should_run(impactassessment)
97
+ assert should_run is expected
98
+ assert len(grouped_inputs) == num_inputs
99
+
100
+
101
+ @patch(f"{class_path}._indicator", side_effect=fake_rounded_indicator)
102
+ def test_run(*args):
103
+ with open(f"{fixtures_folder}/impactassessment.jsonld", encoding='utf-8') as f:
104
+ impactassessment = json.load(f)
105
+
106
+ with open(f"{fixtures_folder}/result.jsonld", encoding='utf-8') as f:
107
+ expected = json.load(f)
108
+
109
+ value = run(impactassessment)
110
+ assert value == expected
111
+
112
+
113
+ @patch(f"{class_path}._new_indicator", side_effect=fake_new_indicator)
114
+ def test_run_no_emissions(*args):
115
+ """
116
+ Impact assessment with no emissions should return a indicator of 0
117
+ """
118
+ with open(f"{fixtures_folder}/impactassessment.jsonld", encoding='utf-8') as f:
119
+ impactassessment = json.load(f)
120
+
121
+ del impactassessment['emissionsResourceUse']
122
+
123
+ value = run(impactassessment)
124
+ assert value['value'] == 0
@@ -0,0 +1,21 @@
1
+ import json
2
+ from tests.utils import fixtures_path
3
+
4
+ from hestia_earth.models.cycle.completeness.freshForage import MODEL, MODEL_KEY, run
5
+
6
+ class_path = f"hestia_earth.models.cycle.{MODEL}.{MODEL_KEY}"
7
+ fixtures_folder = f"{fixtures_path}/cycle/{MODEL}/{MODEL_KEY}"
8
+
9
+
10
+ def test_run():
11
+ with open(f"{fixtures_folder}/cycle.jsonld", encoding='utf-8') as f:
12
+ cycle = json.load(f)
13
+
14
+ assert run(cycle) is True
15
+
16
+
17
+ def test_run_invalid():
18
+ with open(f"{fixtures_folder}/cycle-invalid.jsonld", encoding='utf-8') as f:
19
+ cycle = json.load(f)
20
+
21
+ assert not run(cycle)
@@ -1,7 +1,6 @@
1
1
  from unittest.mock import patch
2
2
  import json
3
3
 
4
- from hestia_earth.models.utils.lookup import factor_value
5
4
  from tests.utils import fixtures_path, fake_new_indicator
6
5
 
7
6
  from hestia_earth.models.edip2003.ozoneDepletionPotential import MODEL, TERM_ID, run
@@ -32,15 +31,4 @@ def test_run_empty_input(*args):
32
31
  impactassessment = json.load(f)
33
32
 
34
33
  result = run(impactassessment)
35
- assert result['value'] is None
36
-
37
-
38
- def test_known_ozone_depletion_lookup_value(*args):
39
- lookup_result = factor_value(
40
- 'edip2003', 'ozoneDepletionPotential', 'emission.csv', 'ozoneDepletionPotential')(
41
- data={
42
- '@type': 'Emission',
43
- 'term': {'@type': 'Term', '@id': '112TrichlorotrifluoroethaneToAirInputsProduction'},
44
- 'value': [1],
45
- })
46
- assert lookup_result == 0.81
34
+ assert result['value'] == 0
@@ -100,8 +100,7 @@ good_during_cycle_indicator_from_forest_to_forest = {
100
100
  "Multiple good indicators => run, 2 dict",
101
101
  ]
102
102
  )
103
- @patch(f"{class_path}.download_all_land_cover_terms",
104
- return_value=[{'@id': 'cropland'}, {'@id': 'seaOrOcean'}, {'@id': 'forest'}])
103
+ @patch(f"{class_path}.get_land_cover_terms", return_value=['cropland', 'seaOrOcean', 'forest'])
105
104
  def test_should_run(mock_download, resources, expected, num_inputs):
106
105
  with open(f"{fixtures_folder}/multipleTransformations/impact-assessment.jsonld", encoding='utf-8') as f:
107
106
  impact = json.load(f)
@@ -28,4 +28,5 @@ def test_run(*args):
28
28
  expected = json.load(f)
29
29
 
30
30
  value = run(impact)
31
+ print(json.dumps(value))
31
32
  assert value == expected
@@ -4,15 +4,13 @@ from os.path import isfile
4
4
  from pytest import mark
5
5
  from unittest.mock import MagicMock, patch
6
6
 
7
- from hestia_earth.models.ipcc2019.aboveGroundBiomass import (
8
- _is_lcc_event, _rescale_category_cover, _should_run, MODEL, run, TERM_ID
9
- )
10
- from hestia_earth.models.ipcc2019.aboveGroundBiomass_utils import BiomassCategory, sample_constant
7
+ from hestia_earth.models.ipcc2019.aboveGroundBiomass import _build_col_name, _should_run, MODEL, run, TERM_ID
8
+ from hestia_earth.models.ipcc2019.biomass_utils import BiomassCategory, sample_constant
11
9
 
12
10
  from tests.utils import fake_new_measurement, fixtures_path
13
11
 
14
12
  class_path = f"hestia_earth.models.{MODEL}.{TERM_ID}"
15
- utils_path = f"hestia_earth.models.{MODEL}.{TERM_ID}_utils"
13
+ utils_path = f"hestia_earth.models.{MODEL}.biomass_utils"
16
14
  term_path = "hestia_earth.models.utils.term"
17
15
  property_path = "hestia_earth.models.utils.property"
18
16
 
@@ -40,6 +38,7 @@ PARAMS_SHOULD_RUN = [
40
38
  ("forest-to-cropland-lcc-q2", True),
41
39
  ("forest-to-cropland-lcc-q3", True),
42
40
  ("forest-to-cropland-lcc-q4", True),
41
+ ("forest-to-gohac", False),
43
42
  ("forest-to-orchard", True),
44
43
  ("forest-to-orchard-with-backup-factors", True),
45
44
  ("forest-to-orchard-with-in-category-lcc", True),
@@ -119,64 +118,29 @@ def test_run_with_stats(
119
118
 
120
119
 
121
120
  # input, expected
122
- PARAMS_RESCALE_CATEGORY_COVER = [
123
- (
124
- {BiomassCategory.ANNUAL_CROPS: 90},
125
- {BiomassCategory.ANNUAL_CROPS: 90, BiomassCategory.OTHER: 10}
126
- ),
127
- (
128
- {BiomassCategory.OTHER: 90},
129
- {BiomassCategory.OTHER: 100}
130
- ),
131
- (
132
- {BiomassCategory.ANNUAL_CROPS: 60, BiomassCategory.VINE: 60},
133
- {BiomassCategory.ANNUAL_CROPS: 50, BiomassCategory.VINE: 50}
134
- ),
135
- (
136
- {BiomassCategory.NATURAL_FOREST: 100},
137
- {BiomassCategory.NATURAL_FOREST: 100}
138
- )
121
+ PARAMS_BUILD_COLUMN_NAME = [
122
+ (BiomassCategory.ANNUAL_CROPS, "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_ANNUAL_CROPS"),
123
+ (BiomassCategory.COCONUT, "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_COCONUT"),
124
+ (BiomassCategory.FOREST, "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_FOREST"),
125
+ (BiomassCategory.GRASSLAND, "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_GRASSLAND"),
126
+ (BiomassCategory.JATROPHA, "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_JATROPHA"),
127
+ (BiomassCategory.JOJOBA, "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_JOJOBA"),
128
+ (BiomassCategory.NATURAL_FOREST, "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_NATURAL_FOREST"),
129
+ (BiomassCategory.OIL_PALM, "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_OIL_PALM"),
130
+ (BiomassCategory.OLIVE, "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_OLIVE"),
131
+ (BiomassCategory.ORCHARD, "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_ORCHARD"),
132
+ (BiomassCategory.OTHER, "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_OTHER"),
133
+ (BiomassCategory.PLANTATION_FOREST, "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_PLANTATION_FOREST"),
134
+ (BiomassCategory.RUBBER, "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_RUBBER"),
135
+ (BiomassCategory.SHORT_ROTATION_COPPICE, "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_SHORT_ROTATION_COPPICE"),
136
+ (BiomassCategory.TEA, "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_TEA"),
137
+ (BiomassCategory.VINE, "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_VINE"),
138
+ (BiomassCategory.WOODY_PERENNIAL, "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_WOODY_PERENNIAL"),
139
+ ("Miscellaneous value", "AG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_OTHER")
139
140
  ]
140
- IDS_RESCALE_CATEGORY_COVER = ["fill", "fill w/ other", "squash", "do nothing"]
141
-
142
-
143
- @mark.parametrize("input, expected", PARAMS_RESCALE_CATEGORY_COVER, ids=IDS_RESCALE_CATEGORY_COVER)
144
- def test_rescale_category_cover(input: dict, expected: dict):
145
- assert _rescale_category_cover(input) == expected
146
-
147
-
148
- # a, b, expected
149
- PARAMS_IS_LCC_EVENT = [
150
- (
151
- {
152
- "appleTree": 33.333,
153
- "pearTree": 33.333,
154
- BiomassCategory.ANNUAL_CROPS: 33.334,
155
- },
156
- {
157
- "appleTree": 33.33333,
158
- "pearTree": 33.33333,
159
- BiomassCategory.ANNUAL_CROPS: 33.33334,
160
- },
161
- True
162
- ),
163
- (
164
- {
165
- "appleTree": 33.3333,
166
- "pearTree": 33.3333,
167
- BiomassCategory.ANNUAL_CROPS: 33.3334,
168
- },
169
- {
170
- "appleTree": 33.33333,
171
- "pearTree": 33.33333,
172
- BiomassCategory.ANNUAL_CROPS: 33.33334,
173
- },
174
- False
175
- )
176
- ]
177
- IDS_IS_LCC_EVENT = ["True", "False"]
141
+ IDS_BUILD_COLUMN_NAME = [p[0] for p in PARAMS_BUILD_COLUMN_NAME]
178
142
 
179
143
 
180
- @mark.parametrize("a, b, expected", PARAMS_IS_LCC_EVENT, ids=IDS_IS_LCC_EVENT)
181
- def test_is_lcc_event(a: dict, b: dict, expected: bool):
182
- assert _is_lcc_event(a, b) is expected
144
+ @mark.parametrize("input, expected", PARAMS_BUILD_COLUMN_NAME, ids=IDS_BUILD_COLUMN_NAME)
145
+ def test_build_col_name(input: BiomassCategory, expected: str):
146
+ assert _build_col_name(input) == expected
@@ -0,0 +1,146 @@
1
+ import json
2
+ from numpy.typing import NDArray
3
+ from os.path import isfile
4
+ from pytest import mark
5
+ from unittest.mock import MagicMock, patch
6
+
7
+ from hestia_earth.models.ipcc2019.belowGroundBiomass import _build_col_name, _should_run, MODEL, run, TERM_ID
8
+ from hestia_earth.models.ipcc2019.biomass_utils import BiomassCategory, sample_constant
9
+
10
+ from tests.utils import fake_new_measurement, fixtures_path
11
+
12
+ class_path = f"hestia_earth.models.{MODEL}.{TERM_ID}"
13
+ utils_path = f"hestia_earth.models.{MODEL}.biomass_utils"
14
+ term_path = "hestia_earth.models.utils.term"
15
+ property_path = "hestia_earth.models.utils.property"
16
+
17
+ fixtures_folder = f"{fixtures_path}/{MODEL}/{TERM_ID}"
18
+
19
+ _ITERATIONS = 1000
20
+
21
+
22
+ def _load_fixture(path: str, default=None):
23
+ if isfile(path):
24
+ with open(path, encoding="utf-8") as f:
25
+ return json.load(f)
26
+ return default
27
+
28
+
29
+ def _fake_calc_descriptive_stats(arr: NDArray, *_args, **_kwargs):
30
+ return {"value": [round(row[0], 6) for row in arr]}
31
+
32
+
33
+ # subfolder, should_run
34
+ PARAMS_SHOULD_RUN = [
35
+ ("forest-to-animal-housing", False),
36
+ ("forest-to-cropland", True),
37
+ ("forest-to-cropland-greater-than-100", True),
38
+ ("forest-to-cropland-less-than-100", True),
39
+ ("forest-to-cropland-lcc-q2", True),
40
+ ("forest-to-cropland-lcc-q3", True),
41
+ ("forest-to-cropland-lcc-q4", True),
42
+ ("forest-to-gohac", False),
43
+ ("forest-to-orchard", True),
44
+ ("forest-to-orchard-with-in-category-lcc", True),
45
+ ("historical-land-cover-mix", True),
46
+ ("historical-argentina-pasture", True),
47
+ ("historical-brazil-maize", True),
48
+ ("perennial-to-grassland-with-pasture-condition", True)
49
+ ]
50
+ IDS_SHOULD_RUN = [p[0] for p in PARAMS_SHOULD_RUN]
51
+
52
+
53
+ @mark.parametrize("subfolder, should_run", PARAMS_SHOULD_RUN, ids=IDS_SHOULD_RUN)
54
+ def test_should_run(subfolder: str, should_run: bool):
55
+ folder = f"{fixtures_folder}/{subfolder}"
56
+
57
+ site = _load_fixture(f"{folder}/site.jsonld", {})
58
+
59
+ result, *_ = _should_run(site)
60
+ assert result == should_run
61
+
62
+
63
+ def test_should_run_no_data():
64
+ SITE = {}
65
+ EXPECTED = False
66
+
67
+ result, *_ = _should_run(SITE)
68
+ assert result == EXPECTED
69
+
70
+
71
+ PARAMS_RUN = [subfolder for subfolder, should_run in PARAMS_SHOULD_RUN if should_run]
72
+
73
+
74
+ @mark.parametrize("subfolder", PARAMS_RUN)
75
+ @patch(f"{class_path}.calc_descriptive_stats", side_effect=_fake_calc_descriptive_stats)
76
+ @patch(f"{class_path}._new_measurement", side_effect=fake_new_measurement)
77
+ @patch(f"{utils_path}._get_sample_func", return_value=sample_constant)
78
+ def test_run(
79
+ _get_sample_func_mock: MagicMock,
80
+ _new_measurement_mock: MagicMock,
81
+ _calc_descriptive_stats_mock: MagicMock,
82
+ subfolder: str
83
+ ):
84
+ folder = f"{fixtures_folder}/{subfolder}"
85
+
86
+ site = _load_fixture(f"{folder}/site.jsonld", {})
87
+ expected = _load_fixture(f"{folder}/result.jsonld", [])
88
+
89
+ with patch(f"{class_path}._ITERATIONS", _ITERATIONS):
90
+ result = run(site)
91
+
92
+ assert result == expected
93
+
94
+
95
+ # subfolder
96
+ PARAMS_RUN_WITH_STATS = [
97
+ "forest-to-cropland-with-stats",
98
+ "forest-to-orchard-with-in-category-lcc-with-stats",
99
+ "historical-land-cover-mix-with-stats"
100
+ ]
101
+
102
+
103
+ @mark.parametrize("subfolder", PARAMS_RUN_WITH_STATS)
104
+ @patch(f"{class_path}._new_measurement", side_effect=fake_new_measurement)
105
+ def test_run_with_stats(
106
+ _new_measurement_mock: MagicMock,
107
+ subfolder: str
108
+ ):
109
+ folder = f"{fixtures_folder}/{subfolder}"
110
+
111
+ site = _load_fixture(f"{folder}/site.jsonld", {})
112
+ expected = _load_fixture(f"{folder}/result.jsonld", [])
113
+
114
+ with patch(f"{class_path}._ITERATIONS", _ITERATIONS):
115
+ result = run(site)
116
+
117
+ assert result == expected
118
+
119
+
120
+ # input, expected
121
+ PARAMS_BUILD_COLUMN_NAME = [
122
+ (BiomassCategory.ANNUAL_CROPS, "BG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_OTHER"),
123
+ (BiomassCategory.COCONUT, "BG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_OTHER"),
124
+ (BiomassCategory.FOREST, "BG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_FOREST"),
125
+ (BiomassCategory.GRASSLAND, "BG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_OTHER"),
126
+ (BiomassCategory.JATROPHA, "BG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_OTHER"),
127
+ (BiomassCategory.JOJOBA, "BG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_OTHER"),
128
+ (BiomassCategory.NATURAL_FOREST, "BG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_NATURAL_FOREST"),
129
+ (BiomassCategory.OIL_PALM, "BG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_OTHER"),
130
+ (BiomassCategory.OLIVE, "BG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_OTHER"),
131
+ (BiomassCategory.ORCHARD, "BG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_OTHER"),
132
+ (BiomassCategory.OTHER, "BG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_OTHER"),
133
+ (BiomassCategory.PLANTATION_FOREST, "BG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_PLANTATION_FOREST"),
134
+ (BiomassCategory.RUBBER, "BG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_OTHER"),
135
+ (BiomassCategory.SHORT_ROTATION_COPPICE, "BG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_OTHER"),
136
+ (BiomassCategory.TEA, "BG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_OTHER"),
137
+ (BiomassCategory.VINE, "BG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_OTHER"),
138
+ (BiomassCategory.WOODY_PERENNIAL, "BG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_OTHER"),
139
+ ("Miscellaneous value", "BG_BIOMASS_EQUILIBRIUM_KG_C_HECTARE_OTHER")
140
+ ]
141
+ IDS_BUILD_COLUMN_NAME = [p[0] for p in PARAMS_BUILD_COLUMN_NAME]
142
+
143
+
144
+ @mark.parametrize("input, expected", PARAMS_BUILD_COLUMN_NAME, ids=IDS_BUILD_COLUMN_NAME)
145
+ def test_build_col_name(input: BiomassCategory, expected: str):
146
+ assert _build_col_name(input) == expected